## DEV Community

Keff

Posted on • Updated on

# [Challenge] 🐝 FizzBuzz without if/else

This challenge is intended for Javascript, but you can complete it with any language you like and can.

Most of us will know the FizzBuzz game/exercise and probably have done it many times. It should be a simple and straightforward exercise for most developers...

BUT can you do it without using if/else statements?

## Challenge Description

Write a program that outputs the string representation of numbers from 1 to N.

But for multiples of 3, it should output "Fizz" instead of the number and for the multiples of 5 output "Buzz". For numbers which are multiples of both 3 and 5, you should output "FizzBuzz".

Curveball: You must not use if/else statements, and ideally, no ternary operator.

Example:

const n = 15;

/*
Return:
[
"1",
"2",
"Fizz",
"4",
"Buzz",
"Fizz",
"7",
"8",
"Fizz",
"Buzz",
"11",
"Fizz",
"13",
"14",
"FizzBuzz"
]
*/

I will comment my solution in a couple of days.

💪 Best of luck! 💪

Credits:
Cover Image from https://codenewbiesite.wordpress.com/2017/01/29/fizz-buzz/

Stephanie Handsteiner • Edited

Easy, just do it in CSS.

ol {
list-style-type: inside;
}

li:nth-child(3n), li:nth-child(5n) {
list-style-type: none;
}

li:nth-child(3n):before {
content: 'Fizz';
}

li:nth-child(5n):after {
content: 'Buzz';
}

Needs some Markup to display obviously.

Ben Halpern

Ha!

Keff

Magnificent! I knew there were going to be really neat solutions!!

Thanks for sharing your solution 💪

Steven vanZyl

The cleanest and best FizzBuzz implementation I know of doesn't use any if statements at all. Actually it doesn't use any control flow at all in most languages.
The approach is fully described here: philcrissman.net/posts/eulers-fizz...

On my Repl.it I also have this same approach implemented in several other languages:
repl.it/@rushsteve1/

Corey Alexander

This was great! Love it when there is a simple probable mathematic solution to these kinds of things!

Keff

Me too, so clean! I love maths but I'm crap at it myself xD

Keff

agtoever • Edited

Holy sh*t, my other solution was really ugly! :-o
Here is a (much) better one (also in Python3):

def fizzbuzz(n):
for i in range(1, n + 1):
print([f'{i}', f'Fizz', f'Buzz', f'FizzBuzz'][(i % 3 == 0) + 2 * (i % 5 == 0)])

fizzbuzz(22)

This works using the property that True in Python has numerical value 1 and using f-strings in an array. The proper element in the array is chosen based on the mentioned property, checking for divisibility with 3 and 5.

nastyox • Edited

# logical operators

The second half of an "and" statement only evaluates if the first half is true.

for(var i = 1; i < 100; i++){
!(i % 3) && document.write("fizz");
!(i % 5) && document.write("buzz");
i % 3 && i % 5 && document.write(i);
document.write(" ");
}

...

# for loops

For loops check your second declaration on each iteration. Force it to be false on the second iteration, and you've got something that'll check your condition a single time.

for(var i = 1; i < 100; i++){
for(var j = 0; !j && !(i % 3); j++) document.write("fizz");
for(var j = 0; !j && !(i % 5); j++) document.write("buzz");
for(var j = 0; !j && i % 3 && i % 5; j++) document.write(i);
document.write(" ");
}

...

# arrays

Referencing an index that that exists gives you the value stored there, but referencing an index that doesn't exist gives you undefined. Use an "or" statement to give yourself a fallback value when this happens, and you'll be ready to go.

var fizz = ["fizz"], buzz = ["buzz"];
for(var i = 1; i < 100; i++) document.write((((fizz[i % 3] || "") + (buzz[i % 5] || "")) || i) + " ");

Or, fill an array with your options, and leverage the fact that true can be used as 1 in JavaScript to do some index-selection math.

var arr = [null, "fizz", "buzz", "fizzbuzz"];
for(var i = 1; i < 100; i++){
arr[0] = i;
document.write(arr[!(i % 3) + !(i % 5) * 2] + " ");
}

...

# try/catch blocks

You can purposefully throw exceptions when a boolean is false by referencing a variable that doesn't exist (the "throwException" variable in this case).

function tryIf(test, pass, fail){
try{
!test || throwException;
(fail || function(){})();
}
catch(e){
pass();
}
}

for(var i = 1; i < 100; i++){
tryIf(!(i % 3), function(){
document.write("fizz");
});

tryIf(!(i % 5), function(){
document.write("buzz");
});

tryIf(i % 3 && i % 5, function(){
document.write(i);
});

document.write(" ");
}

...

# while loops

This is the same concept as for loops. Force the loop to stop after one iteration (this time with a break), and you've got something that'll check your condition a single time.

for(var i = 1; i < 100; i++){
while(!(i % 3)){
document.write("fizz");
break;
}

while(!(i % 5)){
document.write("buzz");
break;
}

while(i % 3 && i % 5){
document.write(i);
break;
}

document.write(" ");
}

...

# switch statements

Who could forget the classic alternative to if statements? Technically not even cheating!

for(var i = 1; i < 100; i++){
switch(i % 3){
case 0:
document.write("fizz");
default:
}

switch(i % 5){
case 0:
document.write("buzz");
default:
}

switch(!(i % 3 && i % 5)){
case false:
document.write(i);
default:
}

document.write(" ");
}

Keff

Wow, those are some solutions right there! Thanks a lot for sharing and taking the time to explain it.

I did some silly stuff, just for fun lol:

function fizzBuzz(number = 100) {
let current = 1;
let string = '';

while (current <= number) {
string += current + ' ';
current += 1;
}

string = string.trim()
.replace(/[0-9]+/g, (match) => {
const valueMap = ['FizzBuzz', match];
const index = match % 15;
return valueMap[index] || match;
})
.replace(/[0-9]+/g, (match) => {
const valueMap = ['Fizz', match];
const index = match % 3;
return valueMap[index] || match;
})
.replace(/[0-9]+/g, (match) => {
const valueMap = ['Buzz', match];
const index = match % 5;
return valueMap[index] || match;
})

return string.split(' ');
}

Here's the simplest I can think of without any statements. 🙃

function run(n, i=1, j=1, k=1, acc=[]) {
!j && k && acc.push('fizz')
!k && j && acc.push('buzz')
!k && !j && acc.push('fizzbuzz')
k && j && acc.push(i)

n - 1 && run(n - 1, i + 1, (j + 1) % 3, (k + 1) % 5, acc)
return acc
}

console.log(run(30))

Keff

Nice, recursion for the win 💪

Keff

Thanks for sharing!

Heiker • Edited

You can still have flow control with functions.

const troo = (iff, elz) => iff;
const falz = (iff, elz) => elz;
const choose = (value) => [falz, troo][Number(Boolean(value))];

const is_fizz = (n) => choose(n % 3 === 0);
const is_buzz = (n) => choose(n % 5 === 0);

const fizzbuzz = (n) =>
is_fizz(n) (
() => is_buzz (n) ("FizzBuzz", "Fizz"),
() => is_buzz (n) ("Buzz", n),
)
.call();

const range = (end) =>
new Array(end).fill(null).map((val, index) => index + 1);

range(15).map(fizzbuzz).join(", ");

Keff

I liked this approach! Thanks for sharing!

Ehsan Azizi • Edited

#### Here is an ugly solution in one line

for (let i = 1; i <= number; i++) {
console.log((i % 3 === 0 && i % 5 === 0 && 'fizzbuzz') || (i % 3 === 0 && 'fizz') || (i % 5 === 0 && 'buzz') || i);
}

Shravan Kumar B

U aren't supposed to use Ternary Operator.

Ehsan Azizi • Edited

Oh yeah! didn't notice that, I have updated my solution

mintyPT

Here is some python for you :)

print([
(not (i % 3) and not (i % 5) and "FizzBuzz") or
(not (i % 3) and "Fizz") or
(not (i % 5) and "Buzz") or
i
for i in range(1,16)])

JP Antunes

There was a similar and equally really good thread about a month ago that had some devilishly clever solutions... highly recommend it!

My contributions below:

//1
const fizzBuzz = n => {
const mapper = (arr, modulo, txt) => arr
.filter(e => e % modulo == 0)
.forEach(e => arr[arr.indexOf(e)] = txt);
let x = 1;
const range = [...Array(n)].map(_ => x++)
mapper(range, 15, 'FizzBuzz');
mapper(range, 5, 'Buzz');
mapper(range, 3, 'Fizz');
return range.toString();
}

//2
const fizzBuzz = n => {
let x = 1;
const range = [...Array(n)].map(_ => x++);
for (let i = 2; i <= n; i += 3) range[i] = 'Fizz';
for (let i = 4; i <= n; i += 5) range[i] = 'Buzz';
for (let i = 14; i <= n; i += 15) range[i] = 'FizzBuzz';
return range.toString();
}

//3
const fizzBuzz = n => {
const isFizzBuzz = n => ( {false: '', true: 'Fizz'}[n % 3 == 0]
+ {false: '', true: 'Buzz'}[n % 5 == 0]
|| n.toString() );
let x = 1;
return [...Array(n)].map(_ => isFizzBuzz(x++)).toString();
}

//4 ...originally from a Kevlin Henney presentation here: https://youtu.be/FyCYva9DhsI?t=1191
const fizzBuzz = n => {
const test = (d, s, x) => n % d == 0 ? _ => s + x('') : x;
const fizz = x => test(3, 'Fizz', x);
const buzz = x => test(5, 'Buzz', x);
return fizz(buzz(x => x))(n.toString());
}

Keff

Nice stuff. I will be checking out the thread!

There have been some really clever solutions posted here as well.

Shravan Kumar B • Edited
function fizzBuzz(n){
let arr = [ ];
for(i=1 ; i<=n; i++){
let flag = i%15==0 && arr.push('FizzBuzz') || i%5==0 && arr.push('Buzz') || i%3==0 && arr.push('Fizz');
!flag && arr.push(i);
}

return arr;
}

console.log(fizzBuzz(15));

Manolo Edge
@nombrekeff

Martin Sebastian • Edited
const fizzBuzz = (until) => {
const fizz = ["Fizz", "", ""];
const buzz = ["Buzz", "", "", "", ""];

(function fizzybuzzy(current) {
console.log(fizz[current % 3] + buzz[current % 5]  || current);

return (current + 1 <= until) && fizzybuzzy(current + 1);
})(0);
}

fizzBuzz(100);

Martin Sebastian • Edited

Some improvement to my earlier version.

A) better (arguably, because way more cognitive load than the very simple one above)

const fizzBuzz = (until, current = 0, fizzbuzz = ["", "Fizz", "Buzz"]) => {
const fizzybuzzy = () => fizzbuzz[!(current % 3) * 1] + fizzbuzz[!(current % 5) * 2]  || current;
return (current + 1 <= until) && (console.log(fizzybuzzy()), fizzBuzz(until, current + 1));
}

fizzBuzz(100);

B) above one as 1 liner b/c hello perl

const devBuzz = (function i(u, c= 0, m=["", "dev", ".to"])  {(c+1<=u) && (console.log(m[!(c % 3)*1] + m[!(c%5)*2] || c), i(u,c+1));});

devBuzz(20);

Martin Sebastian

Also thinking about overriding Number.prototype.toString makes a fun thingy. Maybe someone already did, but someone for sure should :D

My javascript solution, modeled after my C++ solution and then reduced

function fizzbuzz(N) {
for (let i = 1; i <= N; i++) {
let fb = ["", "Fizz", "Buzz", i.toString()];
console.log(fb[(!(i % 3) + 0)]+fb[((!(i % 5)) * 2)]+fb[(((i%3!=0) && (i%5!=0))+0) * 3]);
}
}

Martynas Kan

Really nice idea!

Here's how I did it 😁

const fizzBuzz = (number) => {
const array = Array(number).fill(undefined).map((_, index) => index + 1);
const fiz = array.filter(v => !(v % 3))
const baz = array.filter(v => !(v % 5))
const fizBaz = array.filter(v => !(v % 5) && !(v % 3))

let result = {};
for (let i of array) {
result[i] = i;
}
for (let f of fiz) {
result[f] = 'Fizz';
}
for (let b of baz) {
result[b] = 'Buzz';
}
for (let fb of fizBaz) {
result[fb] = 'FizzBuzz';
}

return Object.values(result);
}

Keff

I just published a new challenge if you want another one :)

Benjamin Trent • Edited

Clojure example.

I quite like Andrew's bit shift array example. Only think that its better to have a nil zeroth value so you get circuit breaking for free.

;; Array for grabbing appropriate string, if exists
(def fizzes [nil "Fizz" "Buzz" "FizzBuzz"])

;; boolean to integer conversion
(defn b-to-i [b]
(bit-and 1 (bit-shift-right (Boolean/hashCode b) 1)))

(defn fizzit [n]
(let [fizzed (b-to-i (= 0 (mod n 3)))                     ;1 if true
buzzed (bit-shift-left (b-to-i (= 0 (mod n 5))) 1)  ;2 if true
both (+ fizzed buzzed)]                             ;3 if both are true
(or (get fizzes both) (str n)))
)

(defn fizzbuzz [n]
(map fizzit (range 1 (inc n))))

wdhowe

One of the ways in Clojure:

(defn divisible?
"Determine if a number is divisible by the divisor with no remainders."
[div num]
(zero? (mod num div)))

(defn fizz-buzz
"Fizz if divisible by 3, Buzz if divisible by 5, FizzBuzz if div by both, n if neither."
[n]
(cond-> nil ; threaded value starts with nil (falsey)
(divisible? 3 n) (str "Fizz") ; if true, adds Fizz to the threaded value (nil)
(divisible? 5 n) (str "Buzz") ; if true, adds Buzz to the threaded value (nil or Fizz)
:always-true     (or n))) ; return the threaded value if not nil (Fizz/Buzz) or n

(let [start 1
stop 20]
(println "FizzBuzz:" start "-" stop)
(doseq [x (range start (+ 1 stop))] (println (fizz-buzz x))))

Original idea seen here: clojuredocs.org/clojure.core/cond-...