library(dplyr)
FizzBuzz
My implementation of FizzBuzz in R, using a vector function.
FizzBuzz
An R implementation of Fizz Buzz, using the instructions from Rosetta Code.
First Implementation
My implementation, written first.
The function:
<- function(x) {
fizz_buzz <- function(n) {
fb_single if (n %% 3 == 0 && n %% 5 == 0) {
"FizzBuzz"
else if (n %% 5 == 0) {
} "Buzz"
else if (n %% 3 == 0) {
} "Fizz"
else {
} # use as.character() so all return values match character(1)
as.character(n)
}
}vapply(x, fb_single, character(1))
}
The task:
fizz_buzz(1:100)
[1] "1" "2" "Fizz" "4" "Buzz" "Fizz"
[7] "7" "8" "Fizz" "Buzz" "11" "Fizz"
[13] "13" "14" "FizzBuzz" "16" "17" "Fizz"
[19] "19" "Buzz" "Fizz" "22" "23" "Fizz"
[25] "Buzz" "26" "Fizz" "28" "29" "FizzBuzz"
[31] "31" "32" "Fizz" "34" "Buzz" "Fizz"
[37] "37" "38" "Fizz" "Buzz" "41" "Fizz"
[43] "43" "44" "FizzBuzz" "46" "47" "Fizz"
[49] "49" "Buzz" "Fizz" "52" "53" "Fizz"
[55] "Buzz" "56" "Fizz" "58" "59" "FizzBuzz"
[61] "61" "62" "Fizz" "64" "Buzz" "Fizz"
[67] "67" "68" "Fizz" "Buzz" "71" "Fizz"
[73] "73" "74" "FizzBuzz" "76" "77" "Fizz"
[79] "79" "Buzz" "Fizz" "82" "83" "Fizz"
[85] "Buzz" "86" "Fizz" "88" "89" "FizzBuzz"
[91] "91" "92" "Fizz" "94" "Buzz" "Fizz"
[97] "97" "98" "Fizz" "Buzz"
To solve this, I first wrote the task, then wrote the function. I took advantage of the fact that R will print the return output of a function by default.
For the function, I wanted to use functional programming and avoid a for()
loop, and only use base R, so I implemented a function for a single case and used vapply()
to apply the function across the vector sequence 1:100
. In my original version, I used unlist(lapply())
because I couldn’t get vapply()
to work. The help for dplyr::case_when()
includes a FizzBuzz example with as.character()
so that the return type is always the same; I adapted this to my initial base R solution.
dplyr
Using dplyr::case_when()
allows much simpler code: (R doesn’t have a built-in ‘case’ statement)
<- function(x) {
fizz_buzz_d ::case_when(
dplyr# x %% 15 == 0 is equivalent to x %% 5 == 0 && x %% 3 == 0
%% 15 == 0 ~ "FizzBuzz",
x %% 5 == 0 ~ "Buzz",
x %% 3 == 0 ~ "Fizz",
x .default = as.character(x)
)
}
fizz_buzz_d(1:100)
[1] "1" "2" "Fizz" "4" "Buzz" "Fizz"
[7] "7" "8" "Fizz" "Buzz" "11" "Fizz"
[13] "13" "14" "FizzBuzz" "16" "17" "Fizz"
[19] "19" "Buzz" "Fizz" "22" "23" "Fizz"
[25] "Buzz" "26" "Fizz" "28" "29" "FizzBuzz"
[31] "31" "32" "Fizz" "34" "Buzz" "Fizz"
[37] "37" "38" "Fizz" "Buzz" "41" "Fizz"
[43] "43" "44" "FizzBuzz" "46" "47" "Fizz"
[49] "49" "Buzz" "Fizz" "52" "53" "Fizz"
[55] "Buzz" "56" "Fizz" "58" "59" "FizzBuzz"
[61] "61" "62" "Fizz" "64" "Buzz" "Fizz"
[67] "67" "68" "Fizz" "Buzz" "71" "Fizz"
[73] "73" "74" "FizzBuzz" "76" "77" "Fizz"
[79] "79" "Buzz" "Fizz" "82" "83" "Fizz"
[85] "Buzz" "86" "Fizz" "88" "89" "FizzBuzz"
[91] "91" "92" "Fizz" "94" "Buzz" "Fizz"
[97] "97" "98" "Fizz" "Buzz"
for loop
The simplest way to solve this is with a for loop:
for (n in 1:100) {
if (n %% 3 == 0 && n %% 5 == 0) {
print("FizzBuzz")
else if (n %% 5 == 0) {
} print("Buzz")
else if (n %% 3 == 0) {
} print("Fizz")
else {
} print(n)
} }
[1] 1
[1] 2
[1] "Fizz"
[1] 4
[1] "Buzz"
[1] "Fizz"
[1] 7
[1] 8
[1] "Fizz"
[1] "Buzz"
[1] 11
[1] "Fizz"
[1] 13
[1] 14
[1] "FizzBuzz"
[1] 16
[1] 17
[1] "Fizz"
[1] 19
[1] "Buzz"
[1] "Fizz"
[1] 22
[1] 23
[1] "Fizz"
[1] "Buzz"
[1] 26
[1] "Fizz"
[1] 28
[1] 29
[1] "FizzBuzz"
[1] 31
[1] 32
[1] "Fizz"
[1] 34
[1] "Buzz"
[1] "Fizz"
[1] 37
[1] 38
[1] "Fizz"
[1] "Buzz"
[1] 41
[1] "Fizz"
[1] 43
[1] 44
[1] "FizzBuzz"
[1] 46
[1] 47
[1] "Fizz"
[1] 49
[1] "Buzz"
[1] "Fizz"
[1] 52
[1] 53
[1] "Fizz"
[1] "Buzz"
[1] 56
[1] "Fizz"
[1] 58
[1] 59
[1] "FizzBuzz"
[1] 61
[1] 62
[1] "Fizz"
[1] 64
[1] "Buzz"
[1] "Fizz"
[1] 67
[1] 68
[1] "Fizz"
[1] "Buzz"
[1] 71
[1] "Fizz"
[1] 73
[1] 74
[1] "FizzBuzz"
[1] 76
[1] 77
[1] "Fizz"
[1] 79
[1] "Buzz"
[1] "Fizz"
[1] 82
[1] 83
[1] "Fizz"
[1] "Buzz"
[1] 86
[1] "Fizz"
[1] 88
[1] 89
[1] "FizzBuzz"
[1] 91
[1] 92
[1] "Fizz"
[1] 94
[1] "Buzz"
[1] "Fizz"
[1] 97
[1] 98
[1] "Fizz"
[1] "Buzz"
The downside to this approach is that it prints each result individually, instead of returning a vector.
Rosetta Code
Note: Rosetta Code offers several different solutions for R. The first solution is cleverer yet still understandable use of base R:
<- function(x) {
fizz_buzz_r <- x
xx %% 3 == 0] <- "Fizz"
xx[x %% 5 == 0] <- "Buzz"
xx[x %% 15 == 0] <- "FizzBuzz"
xx[x
xx
}
fizz_buzz_r(1:100)
[1] "1" "2" "Fizz" "4" "Buzz" "Fizz"
[7] "7" "8" "Fizz" "Buzz" "11" "Fizz"
[13] "13" "14" "FizzBuzz" "16" "17" "Fizz"
[19] "19" "Buzz" "Fizz" "22" "23" "Fizz"
[25] "Buzz" "26" "Fizz" "28" "29" "FizzBuzz"
[31] "31" "32" "Fizz" "34" "Buzz" "Fizz"
[37] "37" "38" "Fizz" "Buzz" "41" "Fizz"
[43] "43" "44" "FizzBuzz" "46" "47" "Fizz"
[49] "49" "Buzz" "Fizz" "52" "53" "Fizz"
[55] "Buzz" "56" "Fizz" "58" "59" "FizzBuzz"
[61] "61" "62" "Fizz" "64" "Buzz" "Fizz"
[67] "67" "68" "Fizz" "Buzz" "71" "Fizz"
[73] "73" "74" "FizzBuzz" "76" "77" "Fizz"
[79] "79" "Buzz" "Fizz" "82" "83" "Fizz"
[85] "Buzz" "86" "Fizz" "88" "89" "FizzBuzz"
[91] "91" "92" "Fizz" "94" "Buzz" "Fizz"
[97] "97" "98" "Fizz" "Buzz"
Of all the solutions, I think using dplyr::case_when()
is the most readable. If I needed a base R solution in the future, I’d pick the Rosetta version.