Or maybe overthink would be more appropriate....
[UPDATE] I've written a followup about why an over-thought solution like the one proposed here can be / is a good thing. And just to be blazingly, obviously, painfully clear on the matter. I do not think that every problem should be over-thought to the degree I took this. My solution represents a crazy amount of code for such a small problem. It's intended as an example of how I'd mentally approach a real and complex problem presented by a client.
The FizzBuzz test was conceived by Irman and posted here: http://tickletux.wordpress.com/2007/01/24/using-fizzbuzz-to-find-developers-who-grok-coding/
It was to be used as a method for weeding out applications for developer positions who couldn't code anything and the original test instructions were to:
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".
ANY developer should be able to write a solution to this and many did in the comments of the original post and other posts that referenced it. Unfortunately, as a number of bloggers pointed out, many of the people who rushed to post solutions GOT IT WRONG! Mostly this was a result of just not reading those three sentences carefully enough. I know, you'd think you wouldn't have to re-read those...
The solutions people were posting were inadvertently providing a classic example of what's wrong with how so many developers approach professional software projects, which means that FizzBuzz is a better interview test than anyone seems to realize. How a person approaches this problem for an interview is a great example of how they'll approach other problems they're faced with should you decide to hire them.
I've been coding professionally for over a decade now and along the way I've learned a number of things; things that I'd like to see addressed either in code or by the questions an interviewee asks in response to the test. So lets set the stage for something a little different.
First, we're going to assume that it's been explained that the FizzBuzz test is based upon a children's game of the same name.
In this game a group of children sit around in a group and say each number in sequence, except if the number is a multiple of three (in which case they say "Fizz") or five (when they say "Buzz"). If a number is a multiple of both three and five they have to say "Fizz-Buzz".
Second, you have to remember that this is for an interview so the response should not only display that they CAN code but, hopefully, give an idea of how they'd approach the task of writing software for one of the interviewer's clients because if someone's hiring you to code then there's a client (even if it happens to be the same company). Seeing if the interviewee can make this logical leap without being told is another part of the test.
Third, after explaining the game the test is based on and with the assumption that the person knows this is for an interview use the same instructions.
Continue reading to see my solution, or pretend you're an interviewee and write something to impress then see how our solutions compare.
This is my solution. It is above and beyond what is needed to address the instructions. But, it's goal was to show an interviewer how I would address the problem if it were for a client of theirs and assumes typical clients. I do not believe that every simple problem needs to be expanded to this extreme. It's written in Java because that's what I have been coding in all day today and you should be able to import it as an existing Java project (compiled against Java 1.6).
It addresses the following issues:
- Clients change their minds. Constantly. Just because it's 1-100 today doesn't mean that it won't need to be -1 to 1000 tomorrow.
- While specs change (see above) wording changes even more. Three days after deploying the code the clients wife / husband will decide that FizzBuzz is a "horribly offensive" term or a foreign student will realise that it means "Dung Beetle Sex" in some obscure language. The words will have to be mutable.
- If it's even remotely useful it'll be re-purposed. Which means the output you thought was appropriate will now need to be usable by the web version, the version for mobile devices, the Blackberry (even though the customer doesn't own any they've demanded Blackberry support).
- Documentation. It's got comments. It's got Javadocs. It's got this document here.
- Readability and maintainability. This is for an interview. The code should be readable not an example of your "leet" mastery of obscure syntax. Furthermore, if this was a "real" app it's just a matter of time before someone else will have to pick up where you left off.
- Unit testing. It's got to be done especially for a mission critical component and I consider successfully obtaining a good job to be a critical mission so this app has got to run correctly. It should also show that I know how to write a good test.
Unfortunately it doesn't address these issues but I would hope that my addressing them in this document will suffice:
- The error messages are NOT internationalized but would definitely need to be in a "real" app. It's far easier to internationalize in the beginning than to re-work an existing app but doing so would have required a bit more work than I thought was appropriate for this app.
- I've also chosen to leave out logging because I wanted this to be runnable without any additional libraries other than jUnit.
- There are no functional tests. Given that the app has no GUI and was to be run from the command line I'll trust that the operating system developers of the world have correctly implemented argument passing to command line apps and that the JVM correctly prints to the console when it needs to. Were this a "real" app with a GUI it would require functional / integration testing.
- It doesn't enable modification of which numbers you'd call out Fizz, Buzz, and FizzBuzz on. This is because the next three prime numbers are 7, 11, and 13. Considering that this is a children's game to teach multiplication none of those would come up with enough regularity to make the game worth playing and non-prime numbers would come up too often.
The unit test assumes you have jUnit 1.4 in your classpath and an easy way to run it, like eclipse.