Production-ready fizzbuzz (Part 1)

Embarking on the Production Journey

Imagine a problem set before you:

Given an array array, your task is to return a string array called answer (1-indexed) where:

  • answer[i] is “FizzBuzz” if i is divisible by both 3 and 5.
  • answer[i] is “Fizz” if i is divisible by 3.
  • answer[i] is “Buzz” if i is divisible by 5.
  • answer[i] is the string representation of i if none of the above conditions are met.

Consider these examples:

Example 1:

Input: $array = range(1,3)
Output: ["1","2","Fizz"]

Example 2:

Input: $array = range(1,5)
Output: ["1","2","Fizz","4","Buzz"]

Example 3:

Input: $array = range(1,15)
Output: ["1","2","Fizz","4","Buzz","Fizz","7","8","Fizz","Buzz","11","Fizz","13","14","FizzBuzz"]

Constraints:

  • 1 <= n <= 10^4

It’s a fundamental programming challenge, testing basic division and loop comprehension. My mission? To craft a production-ready, highly scalable, and pattern-constrained FizzBuzz program using PHP.

Throughout this journey, we’ll progressively enhance the solution, layering in increasingly sophisticated design patterns until we birth a truly refined, functional codebase. One poised for global deployment, destined to be embraced by billions as the definitive FizzBuzz solution.

In Part 1 of this series, our focus lies on crafting a simple, functional FizzBuzz implementation.

Unveiling the Simple Solution

Let’s revisit the problem statement: we’re tasked with processing an integer representing the range of numbers to be assessed. For each number, we check if it’s divisible by 3 or 5, appending “Fizz” or “Buzz” accordingly. If divisible by both, we output “FizzBuzz”. Otherwise, we pass the number unchanged.

Here’s my implementation:

$array = range(1,15);

$answer = array_map(function ($number) {
    $output = '';

    if ($number % 3 == 0) $output .= 'Fizz';
    if ($number % 5 == 0) $output .= 'Buzz';

    return $output ?: $number;
}, $array);

print_r($answer);

This code yields the following output:

Array
(
    [0] => 1
    [1] => 2
    [2] => Fizz
    [3] => 4
    [4] => Buzz
    [5] => Fizz
    [6] => 7
    [7] => 8
    [8] => Fizz
    [9] => Buzz
    [10] => 11
    [11] => Fizz
    [12] => 13
    [13] => 14
    [14] => FizzBuzz
)

I’ve used the built-in array_map() function which iterates over each element of the $array array, applying our lambda function to each element. The result is an array containing the modified elements according to the FizzBuzz logic.

This solution works very well. You might’ve noticed that I haven’t included the edge case of passing in a 0. Our constraint states that the numbers inside the array have to be positive integers up to 10,000 so that is what we will stick to throughout this blog, but in case you were wondering we could easily fix this problem by adding the following statement:

$array = range(0,3);

$answer = array_map(function ($number) {
    $output = '';

    /**
     * This if statement checks if
     * our number is that troublesome
     * zero.
    */
    if ($number === 0) {
        return $number;
    }

    if ($number % 3 == 0) $output .= 'Fizz';
    if ($number % 5 == 0) $output .= 'Buzz';

    return $output ?: $number;
}, $array);

print_r($answer);

So far, so good. The code functions as intended, boasting optimal efficiency with a big O notation of O(n). Yet, our management craves more: they seek complexity, scalability, and modernity.

And that’s precisely what you’ll find in this blog. An evolved FizzBuzz apparatus. In the upcoming chapters, I’ll transform my solution into an object-oriented paradigm, a beacon of modern ingenuity and programmer resourcefulness, by integrating the first design pattern: the Flyweight.