Shortest FizzBuzz

FizzBuzz? What's that?

FizzBuzz is the classic exercise you could get in interviews:

  • We get a list of numbers from 1 to N.
  • When a number is divisible by 3, we change the value to "Fizz".
  • When a number is divisible by 5, we change the value to "Buzz".
  • If we can divide the number by both 3 and 5, we show "FizzBuzz".
  • If none of the above applies, we just keep the number.

So... what's the challenge, then?

I tried to make it more challenging for me, so I decided to make the smallest version of this algorithm I possibly could in JavaScript. This is the one (64 characters long):

[...Array(100)].map((_,i)=>(++i%3?"":"Fizz")+(i%5?"":"Buzz")||i)

Care to explain?

Sure thing, here's the same code with comments:

// We use spread over a newly created array of 100 elements
// without the spread `map` doesn't work because the array is empty...
[...Array(100)]
	// Then we map over it...
	.map(
		// We ignore the first element `_` which is undefined, and use the index `i`
		(_, i) =>
			// First we do ++i because we start in `1` not `0`.
			// We use a ternary so if ++i is divisible by 3 "Fizz", if not empty string.
			(++i % 3 ? "" : "Fizz") +
				// Same as above, but this time with 5 and "Buzz".
				(i % 5 ? "" : "Buzz") ||
			// At this point we have either "Fizz", "Buzz",
			// both concatenated "FizzBuzz", or an empty string, which is falsy.
			// So if we have that falsy value, we go to the index value.
			i
	);

Other ideas

If you don't care about starting with the value 1, then you can remove the ++ making it even smaller:

[...Array(100)].map((_,i)=>(i%3?"":"Fizz")+(i%5?"":"Buzz")||i)

I also tried other variants but is always bigger. This one uses spread with Array.prototype.keys so we don't need to use the index and we can use the value of the items:

[...Array(100).keys()].map(i=>(++i%3?"":"Fizz")+(i%5?"":"Buzz")||i)

Maybe using Array.from? Nope, this is also bigger :'(

Array.from(Array(100),(_,i)=>(++i%3?"":"Fizz")+(i%5?"":"Buzz")||i)

I also tried using that useless _ attribute, like this:

[...Array(100)].map((z="zz",i)=>(++i%3?"":"Fi"+z)+(i%5?"":"Bu"+z)||i)

Or even using nasty declarative stuff like this:

i=0,o=[];while(i++<100)o.push((i%3?"":"Fizz")+(i%5?"":"Buzz")||i)

But it always ends up being bigger... so here's the challenge for you:

Can you make it even smaller?

So yeah, this is the challenge. I was wondering if there are smaller versions of this algorithm that we can achieve in JS. If you have any ideas, leave them in the comment section below.


We have a winner (62 characters long)! (Aug 09, 2021)

@siddharthshyniben made this version which is shorter than mine, now let's see if you can beat him:

a=[];for(i=0;++i<101;a.push(i%5?f||i:f+"Buzz"))f=i%3?"":"Fizz"

Expanded version for the folks wanting to understand this version:

// We create a global variable `a` with an empty array on it:
a = [];

for (
	// other global variable `i` is created with a value of 0:
	i = 0;
	// We loop while i is lower than 101 adding 1 to i each time:
	++i < 101;
	// Per loop we push i to the array `a`, or the value of `f` + "Buzz"
	a.push(i % 5 ? f || i : f + "Buzz")
)
	// `f` is yet another global variable, this time with the "Fizz" part:
	f = i % 3 ? "" : "Fizz";

A new challenger (61 characters long)! (Sep 05, 2021)

With syntax highlight:

a=[i=1];while(i<100)a[i++]=(i%3?"":"Fizz")+(i%5?"":"Buzz")||i

Expanded version for the folks wanting to understand this version:

// We create a global variable `a`
a = [
	// This time we assign 1 to a global `i` inside the array `a`,
	// so we initialize with the value 1 in index 0
	i = 1
];
// We use `while` this time
while (i < 100)
	// And instead of using `push` we assign the `i++` value per loop
	a[i++] =
		// This logic is pretty similar to the original algorithm shown above
		(i % 3 ? "" : "Fizz") + (i % 5 ? "" : "Buzz") || i;

Believe or not, it got shorter (60 chars long)! (Mar 04, 2022)

User @arekx in the comments made it to 60 characters! Here's the snippet:

for(a=[i=0];i<100;)a[i++]=(i%3?'':'Fizz')+(i%5?'':'Buzz')||i

And here's the explanation for you:

// We start with a `for`
for (
	// We create a global `a` and assign an array to it with the first item being `i = 0`
	// This way we assign 0 to both `i` and to the first item of `a`.
	a = [i = 0];
	// We loop while `i` is lower than `100`
	i < 100;
)
	// Every loop we assign to the global `a` in the position `i++`.
	// `++` ads 1 to i but returns the current value, so the first iteration it will be 0
	a[i++] =
		// Finally this logic is pretty sumular to previous approaches, we
		// check `i % 3` for "Fizz" and `i % 5` for Buzz, or we return `i`
		(i % 3 ? "" : "Fizz") + (i % 5 ? "" : "Buzz") || i;

It keeps getting shorter (59 bytes long)! (Jun 18, 2022)

User @posandu in the comments took one byte away from the previous winner by using type coercion in his favor. Here's the snippet:

for(a=i=[];i<100;)a[i++]=(i%3?'':'Fizz')+(i%5?'':'Buzz')||i

Explained version:

// We start with a `for`
for (
	// We create a global `a` and a `i`, and assign and empty array to both of them
	a = i = [];
	// We loop while `i` is lower than `100`
	i < 100;
)
	// Every loop we assign to the global `a` in the position `i++`.
	// `i` initially was `[]`, and when we add `1` to it, it becomes '"1"'
	// and next time it will be `2`, `3` and so on.
	a[i++] =
		// Finally this logic is pretty sumular to previous approaches, we
		// check `i % 3` for "Fizz" and `i % 5` for Buzz, or we return `i`
		(i % 3 ? "" : "Fizz") + (i % 5 ? "" : "Buzz") || i;