Buzzing and Fizzing in PHP

11 08 2010

Purportedly it can be terribly challenging to find a programmer who can actually code (see http://imranontech.com/2007/01/24/using-fizzbuzz-to-find-developers-who-grok-coding/. The article cites the following FizzBuzz problem as a way to determine whether a programmer can actually code:

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

Some may criticize the problem for not being a realistic example of what one would normally encounter at work. The author at the above-indicated url, Imran, feels that a decent programmer should be able to solve this problem with pen and paper in less than 2 minutes.

Frankly, I feel that it’s patently nonsensical for anyone to attempt to demonstrate programming skill using tools one would never employ on the job. I might use pen and paper at work to make a quick sketch for a design, but for writing code, I’d use some sort of editor or IDE on a computer. Furthermore, I’d probably google just to see what others have done. Who knows, maybe I’d devise something better. So, when I decided to go for the above FizzBuzz challenge, I rejected pen and paper in favor of my computer editing software and PHP bundle, and came up with following code example:

for ($i=1, $max = 100; $i <= $max; $i++) {
	switch ($i)
	{
    case ( !($i % 3) && !($i % 5) ):
		echo "<span style='color:blue'>FizzBuzz</span>";
		break;
	case (! ($i % 3) ):
		echo "Fizz";
		break;
	case (! ($i % 5) ):
		echo "Buzz";
		break;
	default:
		echo $i;
		break;
	}
    echo '<br />';
}

The above example was the first way I solved the problem intuitively. The code clearly shows four different cases. The first case shows what happens when a number is divisible by both 3 and 5. After that there’s the case where a number is divisible by 3, followed by the case where it’s divisible by 5. Last case is where the number itself is printed since it doesn’t match any of the other cases.

This code clearly shows that the coder knows the basics regarding using a for-loop, a switch, and a modulo operator and so by inference also is proficient in basic math. What is interesting is that there are some other ways to approach the problem and all will attest that you know something about programming.

I subsequently saw at http://imranontech.com/2007/01/24/using-fizzbuzz-to-find-developers-who-grok-coding/
a different solution, as follows:

for ($x=1;$x <= 100; $x++)
echo ( ( $f3 = $x % 3 )? '' : 'fiz') . ( ( $f5 = $x % 5)? '':'buz') . ( !( !$f3 || !$f5)? $x: '');

As clever as this one liner is, is it what you want to see in production code? The above snippet certainly achieves its intended result, but if another programmer comes along and reviews the code, s/he may be unable to quickly decipher what its purpose is.

In the same article, someone using another language suggested employing ranges, so I decided to try out this idea in PHP, and devised the following:

$threes = range (0,100,3);
$fives = range(0,100,5);
for ($i=1,$max=100; $i <= $max; $i++) {
	if (in_array($i, $threes) && in_array($i, $fives)) {
		echo '<span style="color:green">fizzbuzz</span>';;
	}
	else
	if (in_array($i, $threes)) {
		echo 'fizz';
	}
	else
	if (in_array($i, $fives)) {
		echo 'buzz';
	}
	else {
		echo $i;
	}
}

Of course, those who are more mathematically inclined will observe that the above solution could even be improved by creating one more range. If a number is divisible by 3 and by 5, then clearly it is divisible by the multiple of the two numbers, 15. So, here’s the rewrite:

$threes = range (0,100,3);
$fives = range(0,100,5);
$threesfives = range(0,100,15);

for ($i=1,$max=100; $i <= $max; $i++) {
	if (in_array($i, $threesfives)) {
		echo '<span style="color:fuchsia">fizzbuzz</span>';;
	}
	else
	if (in_array($i, $threes)) {
		echo 'fizz';
	}
	else
	if (in_array($i, $fives)) {
		echo 'buzz';
	}
	else {
		echo $i;
	}
}

You could also solve the problem without ranges or switches, as follows:

for( $x=1, $max=100; $x <= $max; $x++ )
{
    if ( ($x % 5) && ($x % 3) )
	{ 
	        echo $x;
	}
	else
	{		
		if ($x % 3 == 0) echo 'fizz';
		if ($x % 5 == 0) echo 'buzz';
	}	
}

This last example basically says if a number is not divisible by 5 nor 3, then print the number. Otherwise, if divisible by 3, display ‘fizz’ and if divisible by 5 then display ‘buzz’. The consequence of the two if statements is that if a number is divisible by both 3 and 5, then ‘fizbuz’ will display.

There is one more way to solve this problem and that is to use recursion, a technique which can be problematic for a web server because it may impair its performance speed-wise. But, for the sake of thoroughness let’s take a look-see, shall we?

$num = 1;

function fizBuz( $x, $stop=100 )
{
	if ($x > $stop) return;
	else
	if ( ($x % 5) && ($x % 3) )
	{ 
	        echo $x;
	}
	else
	{		
		if ($x % 3 == 0) echo 'fizz';
		if ($x % 5 == 0) echo 'buzz';
	}
	$x++;
	fizBuz($x);
}

fizBuz($num);

The above code shows how to use recursion instead of a for loop to “FizzBuzz.” The function keeps calling itself with its last invocation occurring when the numerical value of $x is one greater than that for $stop.

With a little more thought, I decided to modify my recursion example above, as follows:

$num = 1;

function fizBuz( $x, $strNum='', $stop=100 )
{
	if ($x > $stop) return $strNum;
	else
	if ( ($x % 5) && ($x % 3) )
	{ 
	        $strNum .= $x;
	}
	else
	{		
		if ($x % 3 == 0) $strNum .= 'fizz';
		if ($x % 5 == 0) $strNum .= 'buzz';
	}
	$x++;
	echo fizBuz($x,$strNum);
	
}

echo fizBuz($num);

This example shows among other things, how to use default parameters and return a value using recursion. So, instead of using echo three times every time fizBuz() is invoked, echo is used only when the fizBuz() is invoked. Also, we’re building a FizzBuzz string that when it is finally returned we can either display or do something else with it.

A prospective employer could modify the original problem by suggesting that the job-seeker show how to “FizzBuzz” using three to four different ways and to explain which way is most preferable. That would indicate the coder’s basic programming knowledge as well as his/her ability to problem solve and generate multiple solutions.

This work is licensed under a Creative Commons License
.

Advertisements

Actions

Information

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s




%d bloggers like this: