Shortest FizzBuzz

6 min read

That boring interview exercise

One of the most common exercises in old-school interviews is the classic "FizzBuzz." The instructions for this exercise are pretty simple:

  • 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.

Making it fun

Nowadays, any company with some respect for their candidates would avoid exercises like this, but it is still fun to do some code golf with it to see what's the shortest version we can make. I came up with this 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 I had

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

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

I also tried other variants but it 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 larger. So I opened the challenge to the community:

Let's make it 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 someone reading this article has any ideas, send me a message, and we can add them below.


62 characters long (Aug 09, 2021)

@SiddharthShyniben made this version:

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";

62 characters long (Aug 30, 2022)

@ibrokemycomputer made another 62 characters version. This one includes a console.log:

for(i=0;++i<101;console.log(i%5?f||i:f+"Buzz"))f=i%3?"":"Fizz"

Version with comments:

// We use a for loop
for (
	// Start a global `i` variable with `0`
	i = 0;
	// Every iteration we add `1` to `i` while it is lower than `101`
	++i < 101;
	// We log each iteration
	console.log(
		// `f` here actually comes from the "body" of this `for` loop.
		// If `i` is not divisible by `5` we log `f`, and if is falsy we log `i`
		// Otherwise we log `f` + "Buzz".
		i % 5 ? f || i : f + "Buzz",
	)
)
	// The `f` global is set to an empty string if `i` is not divisible by `3`,
	// and set to "Fizz" if it is.
	f = i % 3 ? "" : "Fizz";

61 characters long (Sep 05, 2021)

User @battlecoder on Twitter made this beauty:

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

Code with explanations:

// 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;

60 characters long (Mar 04, 2022)

User @arekx 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:

// 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;

59 bytes long (Jun 18, 2022)

User @posandu 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;
Share this article