HiveBrain v1.2.0
Get Started
← Back to all entries
patternpythonModerate

Fizz, Buzz, or FizzBuzz?

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
buzzfizzfizzbuzz

Problem

I was messing around online at work the other day when our phone systems went down. I came across the R programming language. Now I'm not guru with programming by any means but I like to mess around with different languages here and there, I believe it helps me to become a better programmer. So I decided that I would try to solve the fizzbuzz challenge in R for those of you that don't know what fizzbuzz is:


Write a program that prints the numbers from 1 to 100. But for multiples of three print "Fizz" instead of the number and for the multiples of five print "Buzz". For numbers which are multiples of both three and five print "FizzBuzz"

This is the first thing I've ever written in R and I would like to have some critique done on what I've accomplished so far:

fizzBuzz = function(range, x, y){
    for (i in seq(1, range, by=1)){
        if (i %% x == 0 & i %% y == 0){
            print('FizzBuzz')
        }
        else if (i %% y ==0){
            print('Buzz')
        }
        else if (i %% x == 0){
            print('Fizz')
        }
        else{
            print(i)
        }
    }
}
fizzBuzz(100, 3, 5)


Some key things I'd like to focus on, per norm feel free to critique everything;

  • Is it a little bit over kill to put this all in a function, obviously I could do it simply without the function, but is this considered good practice in R to put your solutions inside of functions? I only ask because I looked around at peoples code and didn't see very many functions in it.



  • Are there easier ways to create the range? I feel like seq(from, to, by=1) is a little harder to understand then range(from, to)

Solution

Just to add to @flodel's comments, here is a properly vectorized version. One can see this is quite a bit faster, outperforming the parallel option (on 7 cores) by a factor 5. This problem is a quite nice demonstration of why is is worth your time to think about vectorized code:

flodel_fizzbuzz <- function(range = 100, fizz = 3, buzz = 5) {
  s <- 1:range
  is.fizz <- s %% fizz == 0
  is.buzz <- s %% buzz == 0

  s[is.fizz] <- 'Fizz'
  s[is.buzz] <- 'Buzz'
  s[is.fizz & is.buzz] <- 'FizzBuzz'
  return(s)
}


Running the benchmarks from @Gerard's answer (note that vectorizedFizzBuzz isn't truly vectorized):

Unit: milliseconds
                      expr       min        lq      mean    median        uq       max neval  cld
      applyFizzBuzz(range) 296.52224 303.19205 315.76901 309.18860 320.01676 384.18786    20   c 
 vectorizedFizzBuzz(range) 341.41121 356.82580 374.53857 362.45300 372.81459 461.65169    20    d
   parallelFizzBuzz(range) 117.40058 128.91812 158.66095 153.87976 170.76776 288.99613    20  b  
  papasmurfFizzBuzz(range) 292.22177 301.48002 316.31151 307.31605 319.05426 393.53235    20   c 
    flodel_fizzbuzz(range)  27.98101  29.15677  29.93554  29.93097  30.84586  32.09304    20 a


-
I do think functions are a nice way to perform these tasks.

-
The easiest way to create a range of subsequent integers is with :.

This tidyverse version does about equally well (with ~40 ms):

tidy_fizbuzz <- function(range = 100, fizz = 3, buzz = 5) {
  x <- 1:range
  dplyr::case_when(
    x %% (fizz * buzz) == 0 ~ "Fizz Buzz",
    x %% fizz == 0 ~ "Fizz",
    x %% buzz == 0 ~ "Buzz",
    TRUE ~ as.character(x)
  )
}

Code Snippets

flodel_fizzbuzz <- function(range = 100, fizz = 3, buzz = 5) {
  s <- 1:range
  is.fizz <- s %% fizz == 0
  is.buzz <- s %% buzz == 0

  s[is.fizz] <- 'Fizz'
  s[is.buzz] <- 'Buzz'
  s[is.fizz & is.buzz] <- 'FizzBuzz'
  return(s)
}
Unit: milliseconds
                      expr       min        lq      mean    median        uq       max neval  cld
      applyFizzBuzz(range) 296.52224 303.19205 315.76901 309.18860 320.01676 384.18786    20   c 
 vectorizedFizzBuzz(range) 341.41121 356.82580 374.53857 362.45300 372.81459 461.65169    20    d
   parallelFizzBuzz(range) 117.40058 128.91812 158.66095 153.87976 170.76776 288.99613    20  b  
  papasmurfFizzBuzz(range) 292.22177 301.48002 316.31151 307.31605 319.05426 393.53235    20   c 
    flodel_fizzbuzz(range)  27.98101  29.15677  29.93554  29.93097  30.84586  32.09304    20 a
tidy_fizbuzz <- function(range = 100, fizz = 3, buzz = 5) {
  x <- 1:range
  dplyr::case_when(
    x %% (fizz * buzz) == 0 ~ "Fizz Buzz",
    x %% fizz == 0 ~ "Fizz",
    x %% buzz == 0 ~ "Buzz",
    TRUE ~ as.character(x)
  )
}

Context

StackExchange Code Review Q#148439, answer score: 11

Revisions (0)

No revisions yet.