FizzBuzz is an interview question which supposedly helps “filter out 99.5% of programming job candidates” who can’t program. I find this assertion very hard to believe, unless those tested are non-coding managers. But anyway, the problem statement is simple:
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”.
A simple implementation in C# might look like this:
[TestMethod]
public void FizzBuzzSimple()
{
string s;
for (int i = 1; i < 101; i++)
{
s = string.Empty;
if (i % 3 == 0) s += "Fizz";
if (i % 5 == 0) s += "Buzz";
if (s.Length == 0) s = i.ToString();
Console.WriteLine(s);
}
}
Since the algorithm here truly is straightforward and simple, a more interesting exercise might be to consider the ways in which this code might change as the requirements change over time. Something like a kata. (For a fun “simple” problem description from a non-programmer’s point of view, this is hilarious, and all too true: http://failblog.cheezburger.com/share/59643393.)
We’re all familiar with code where the conditional expressions have become both ugly and impenetrable. In fact, we’ve probably “contributed” to these codebases at some point too. Something that may have started with a relatively simple “if ((A and !B) or C)” grows over time to a rat’s nest of and’s, or’s, not’s, etc. So what might change here, and can we, or should we, try to “future proof” against it?
- What if the range changes? Instead of 1 to 100, the user now wants 1 to 1000, or maybe 50 to 100. Maybe the range needs to be user configurable.
- What if our output strings change? Instead of “Fizz” and “Buzz”, the user wants “Buzz” and “Feed”. Should we continue to hardcode magic strings? Maybe we want something entirely different than the “FizzBuzz” concatenation when a multiple of 15 is found. What if we need to localize the strings based on the user’s language?
- What if the test conditions change, or new conditions are added? In practice, this is often the most likely change agent. What if more complex conditions are needed, such as special processing for multiples of 10? How can we make the code easy to read and maintain over time?
- What if the test conditions, in the real world, are expensive in terms of performance? Instead of testing numbers, maybe we’re calling functions which make database or service calls. How do we make this performant?
- What if our user no longer wants to “print” the output? Maybe the output will go to a diagnostics window, log, or screen. Could dependency injection help here?
There are probably myriad more possibilities, but I’m already feeling analysis paralysis.
CodeProject
Filed under: C#, my 2 cents