The FizzBuzz question is an interview task designed to filter out programmers based on a classic maths game; whilst the question is not seen as particularly difficult, it does throw up a lot of problems for even experienced programmers. Successful completion of the task won't guarantee that a programmer is actually "good", but it does give you a fair amount of insight into the thinking that was behind their solution.

So what's the question?

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


1
2
Fizz
4
Buzz
Fizz
7
8
Fizz
Buzz
11
Fizz
13
14
FizzBuz
...
...
97
98
Fizz
Buzz

There are many ways to approach this and on the face of it it sounds pretty easy but the majority of solutions end up being a huge mess of if/else statements that aren't very scalable or user friendly. You can see such an example below.


for($i=1;$i<101;$i++) {

    if (($i % 3 == 0) && ($i % 5 == 0)) {
        echo "FizzBuzz\r\n";

    } elseif ($i % 3 == 0) {
        echo "Fizz\r\n";

    } elseif ($i % 5 == 0) {
        echo "Buzz\r\n";

    } else {
        echo $i . "\r\n";
    
    }

}

Now the above solves the question but it just isn't scalable or efficient at all. For example, if you want to output the Fizz on multiples of 3 and 8; you need to add another elseif statement or an OR logical operator. Disgusting! This is going to get very messy, very quickly! Not to mention all of these additional if/else/logic operators fall foul of the DRY principle (Don't Repeat Yourself) and instead would be classed as a WET solution ("write everything twice", "we enjoy typing" or "waste everyone's time").

So what's a 'good' solution?

Below I've written a few solutions which are by no means perfect but they solve the problem more succinctly, with the last being my favourite. I believe it's easy enough to read and understand whilst also scalable enough to cope with changing demands on the key numbers, simply add other numbers into each array and you're good to go.


// 1
for($i=1; $i < 101; $i++) {
	$output = "";
	$output .= $i % 3 == 0 ? "Fizz" : "";
	$output .= $i % 5 == 0 ? "Buzz" : "";
	echo empty($output) ? $i . "\r\n" : $output ."\r\n";
}


// 2
for($i=1; $i < 101; $i++) {
	$output = "";
    if($i % 3 == 0) $output .= "Fizz";
    if($i % 5 == 0) $output .= "Buzz";
	echo empty($output) ? $i . "\r\n" : $output ."\r\n";
}


// 3
$numbers = ["fizz" => [3], "buzz" => [5]];
// Incase you want to add aditional numbers, you can add them like the below
// $numbers = ["fizz" => [3, 11], "buzz" => [5, 22, 43]];
for($i=1; $i<101; $i++) {
	$output = "";
	foreach (array_keys($numbers) as $key) {
		for($ii=0; $ii < count($numbers[$key]); $ii++) {
			if($i % $numbers[$key][$ii] == 0) {
				$output .= ucwords($key);
				break;
			}
		}
	}
	echo empty($output) ? $i . "\r\n" : $output ."\r\n";
}