Skip to content

Instantly share code, notes, and snippets.

@alangfiles
Last active August 29, 2015 14:05
Show Gist options
  • Save alangfiles/fb12363d4319279f3f2a to your computer and use it in GitHub Desktop.
Save alangfiles/fb12363d4319279f3f2a to your computer and use it in GitHub Desktop.
Progression through some fizzbuzz golf

#FizzBuzzin' I recently read another article about how programmers don't know how to program FizzBuzz (I'm not sure I buy it, but who am I to argue with numbers). Anyway, I decided to write it myself in javascript real quickly, and then I decided to try to golf it down, and see how few characters I could use. What follows are my attempts:

Unfortunately, I didn't really set up a formal requirement for my program, does it need to be a function, where does the output have to go to, etc. So I kinda just wing it on some of those questions, and it changes over time.

##first attempt

function fizzBuzz(){
	for (var i =1; i < 101; i++) {
		var o = '';
		if(i%3 == 0){
			o += "Fizz";
		}
		if(i%5 == 0){
			o += "Buzz";
		}
		if(i%3 != 0 && i%5 != 0){
			o += i;
		}
		console.log(o);
	}
}

-204 Chars

##second attempt remove the n%x == 0 piece, and use !(n%x) because if it divides evenly the answer is 0 which is false

 function fizzBuzz(){
	for (var i =1; i < 101; i++) {
		var o = '';
		if(!(i%3)){
			o += "Fizz";
		}
		if(!(i%5)){
			o += "Buzz";
		}
		if(i%3 && i%5){
			o += i;
		}
		console.log(o);
	}
}

-190

##third attempt start just using ternary statements. removing some whitespace.

function fizzBuzz(){
	for (var i =1; i < 101; i++) {
		var o='';
		o=(!(i%3)?"Fizz":o);
		o+=(!(i%5)?"Buzz":'');
		o+=(i%3 && i%5?i:'');
		console.log(o);
	}
}

-159

##fourth attempt changed last line of logic to test if o is empty instead of big number test.

function fizzBuzz(){
	for (var i=1; i<101; i++){
		var o='';
		o=(!(i%3)?"Fizz":o);
		o+=(!(i%5)?"Buzz":'');
		o+=(!(o)?i:'');
		console.log(o);
	}
}

-149

##fifth attempt WHO NEEDS A THIRD CASE, throw it in the with second.

function fizzBuzz(){
	for (var i=1; i<101; i++){
		var o='';
		o=(!(i%3)?"Fizz":o);
		o+=(!(i%5)?"Buzz":!(o)?i:'');
		console.log(o);
	}
}

-138 chars

##sixth attempt No need for variable declaration as it's own line either

function fizzBuzz(){
	for(var i=1; i<101; i++){
		var o=(!(i%3)?"Fizz":'');
		o+=(!(i%5)?"Buzz":!(o)?i:'');
		console.log(o);
	}
}

-130 chars

##seventh attempt no need for the o var, just print it out in 2 added strings (needed to bring back test for printing number only (i%3 && i%5))

function fizzBuzz(){
	for (var i=1; i<101; i++){
		console.log((!(i%3)?"Fizz":'')+(!(i%5)?"Buzz":(i%3 && i%5)?i:''));
	}
}

-122 chars

##eighth attempt a foray into recursion. I'm not so happy with the result, since the function name is now shortened, and it only saves 4 characters, but this could be a good direction.

function f(i){
	i=(!(i)?1:i);
	console.log((!(i%3)?"Fizz":'')+(!(i%5)?"Buzz":(i%3 && i%5)?i:''));
	if(i<100){f(i+1)}
}

-118 chars

##nineth attempt gave up my previous aversion to anonymous functions, and now passing in the starting number value (1)

(function f(i){
	console.log((!(i%3)?"Fizz":'')+(!(i%5)?"Buzz":(i%3 && i%5)?i:''));
	(i<100?f(i+1):0);
})(1);

-109 chars

##tenth attempt using if statement in recursive call for readability, also removed extra whitespace (note: whitespace is left in the example, but character count is updated from now on, taking out whitespace)

(function f(i){
  console.log((!(i%3)?"Fizz":'')+(!(i%5)?"Buzz":(i%3 && i%5)?i:''));
  if(i<100){f(i+1)}
})(1);

-111 chars (104 chars with whitespace removed)

##eleventh attempt if I start at 100 and recursively go to 1, I can put the if in front, and then I don't need a ; between it and the console.log()

(function f(i){
  if(i>0){f(i-1)}
  console.log((!(i%3)?"Fizz":'')+(!(i%5)?"Buzz":(i%3 && i%5)?i:''))
})(100)

-102 chars with whitespace removed

##twelveth attempt when i = 0 it'll register as false, so no need to check i>0

(function f(i){
  if(i){f(i-1)}
  console.log((!(i%3)?"Fizz":'')+(!(i%5)?"Buzz":(i%3 && i%5)?i:''))
})(100)

-100 chars with whitespace removed

##thirteenth attempt realized I didn't need {} around the if statement if i used a ; UNDER 100!!!

(function f(i){
  if(i)f(i-1);
  console.log((!(i%3)?"Fizz":'')+(!(i%5)?"Buzz":(i%3 && i%5)?i:''))
})(100)

-99 chars (but a fizzbuzz ain't one) with whitespace removed. Also, pretty sure f(i){if(i)f(i-1) is a palindrome, but I'm too lazy to check.

##fourteenth attempt bad news sports fans, my last one checked from 0 - 100. not 1 - 100. so it doesn't work under my strict requirements... unlucky 13

(function f(i){
  if(i--)f(i-1);
  console.log((!(i%3)?"Fizz":'')+(!(i%5)?"Buzz":(i%3 && i%5)?i:''))
})(100)

-101 chars with whitespace removed

##fifteenth attempt good news golf fans! I realized that after the buzz check, I just need to check if it's divisible by 3 to know if I need to ouput the number only.

(function f(i){
  if(i-1)f(i-1);
  console.log((!(i%3)?"Fizz":'')+(!(i%5)?"Buzz":(i%3?i:'')))
})(100)

-94 chars with whitespace removed

##sixteenth attempt wow, rearranged my logic so I didn't need the !'s and then I could lose the parens around them.

(function f(i){if(i-1)f(i-1);console.log((i%3?'':'Fizz')+(i%5?i%3?i:'':"Buzz"))})(100)

-86 chars

##seventeenth attempt was able to remove 1 character by going to ternary statement for recursion.

(function f(i){i-1?f(i-1):0;console.log((i%3?'':'Fizz')+(i%5?i%3?i:'':"Buzz"))})(100)

-85 chars

#Post Mortem So, after my 17th attempt, I gave up, and googled (binged?) what other people had done, and the best I found was as follows:

for(var i=1;i<101;i++){alert((i%3?"":"fizz")+(i%5?"":"buzz")||i)};

-66 chars (from StackOverflow reject question by Mark Robinson)

Then found an even better version:

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

-64 chars (from StackOverflow by User Noctis)

the only update I would have to that is to remove the {} braces, and the semicolon in the first one, and change to console.log, just to match everything else, somewhere along the line I thought of using alert, but decided (arbitrarily) that the output had to be to console.log and that global variables weren't allowed (i in the second example).

Those are pretty great code examples, and I really like the fun trick in (i%3?'':'Fizz')+(i%5?'':'Buzz')||i. The thought of just going through the for loop, without defining a function is a good idea that I was blind to.

So using the above examples, I'd come up with:

for(var i=0;i<100;)console.log((++i%3?'':'Fizz')+(i%5?'':'Buzz')||i)

-68 chars

And so here is the smallest possible version I can think of, ignoring my rules against globals and alert (It's really just Noctis' version, but using alert).

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

-58 characters

##Rejects

###Reject 1 This one removes 2 parenthesis, and replaces them with the ! at the function start. But it returns true at the end of the stream, so I disqualified it, but it saves 1 character over my 17th attempt (although the 17th attempt also returns 'undefined' at the end, so maybe this should count).

!function f(i){i-1?f(i-1):0;console.log((i%3?'':'Fizz')+(i%5?i%3?i:'':"Buzz"))}(100)

-84 chars

###Reject 2 For this one I tried passing in 'Fizz' and 'Buzz', and using one logic statement, but it was no better than anything else. The only interesting trick here was to pass a variable in to the function so I don't have to do var x =, I also replaced all the internal logic to be one piece that calculates fizz, buzz, and fizzbuzz without concatenation. This thing saved no space, but was kinda fun.

(function f(i,z,b){
  i-1?f(i-1,z,b):0;
  console.log((i%3?(i%5?i:b):(i%5?z:z+b)))
})(100,'Fizz','Buzz')

-97 chars with whitespace removed

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment