You should follow me on Twitter

PHP Code Golfing – ‘FizzBuzz’

May 8th, 2011 - 1:13 pm | 1 Comment | Code, Hacks, Projects

Back in 2007 I read an interesting article about programmers whom can’t actually program, probably shocking to some but not to those that remember Sturgeon’s Law (90% of everything is crap). A quick glance at the program described and I already had the code floating around in my head, trivial for a seasoned programmer.

The description of the program is as follows:

Write a program that prints the numbers from 1 to 100. But for multiples of three print “Fizz” instead of the number and for the multiples of five print “Buzz”. For numbers which are multiples of both three and five print “FizzBuzz”.

Soon thereafter I discovered the concept of ‘code golfing’ and was intrigued. I quickly rationalized that it was the best ways to teach bad coding practices, but at the same time give invaluable insight into the infrequently used operations of the language – some that might one day save a lot of grief. Thus my spiral into madness began as I set out to make the worlds smallest working version of the trivial FizzBuzz in PHP. Drinking might have been involved in this decision.

Let’s start with a clean example of FizzBuzz coded in PHP weighing in at a 329 bytes:

<?php
// Simple FizzBuzzer by Lorin
for ($num=1; $num<=100; $num++) { 
    if ($num%3==0 || $num%5==0) {	// is $num divisible by 3 or 5?
      if ($num%3==0) echo 'Fizz';	// Modulus instead of division
      if ($num%5==0) echo 'Buzz';
    } else echo $num; // otherwise display number
    echo "\r\n"; // new line!
}
?>

Ok, easily readable – works fine. Now let’s golf, but I’ll skip to the conclusion because that’s why you’re reading this article, isn’t it?

But before that, I’d like to note code that looks like the following rarely has any reason to exist other than being a personal challenge. The two major exceptions to this would be coding a demo scene intro where the goals are quite similar to those of code golf, or where code space is at an extreme premium, which is becoming much less relevant these days.

Here’s the svelte 57 byte result, a 5.7x decrease in code base!

<?while($i++ <100)echo$i%3?!$$i=$i:Fizz,$i%5?$$i:Buzz,~õ?>

There are some parts of this code which are (understandably) confusing, let’s break it down:

  • Removing all the comments and shorting variable names – we’re going for computer executability, not human readability, so let’s remove anything that could possibly explain what this code does other than the code itself. Let’s also assume short tags are enabled on the server.
  • Shortening the loop – this was the easiest of all the shorthands tricks. I’d probably use this if I’m banging out code quickly for a proof of concept. It loops from 1 to 100, a neat off-by-one effect.
  • Ternary operators – probably the most confusing, the modulus operator returns 0 when ‘true’, so I flipped the true and false functions in this case. A slightly larger version utilized three stacked ternary operators and it was really annoying to debug
  • Setting a variable within an echo prints it out. Throwing a ! in front of it seemed to do the trick, its used in tandem with a variable variable to solve a core issue when using only using two ternary operations. This could be explored a bit further.
  • Utilizing unset constant variables instead of strings. On a system with reduced warnings you can drop the quotes around ‘Fizz’ and ‘Buzz’ saving 2 bytes at every instance
  • Variable Variables – This is evil. Every time the code loops we are creating a new variable and eating up memory. Even worse is that we are creating a new variable named after the current number(!) with its contents being the same, which is theoretically impossible as PHP doesn’t directly allow setting/reading numeral based variables (ex. $36 would be invalid). This took me the longest to figure out and was only discovered with the help of a peer. Nightmarish stuff…
  • Where is the new line in all this? It got bit flipped! Instead of “\r\n” (6 bytes) or a physical new-line ascii character (3 bytes), I utilize the ~ bitwise operator that inverts the ‘õ’ character into the new-line character, in a total of 2 bytes! This was the largest “AHA!” moment for me, although it might not work in some versions of PHP.

So there you have it, the smallest version of FizzBuzz possible in PHP, although I look forward to one day being beat by someone else. No cheating by loading from external sources! :)

↑ Post a Comment (1)
You can safely stop scrolling now.