FizzBuzz

Created 16th July, 2008 07:27 (UTC), last edited 16th July, 2008 08:48 (UTC)

The Bangkok BeerCamp meetings are starting to settle down with a more regular crowd now and I thought it might be interesting to introduce a programming puzzle to them so we can keep our geeky focus in downtown Bangkok.

As it's now only a few hours until we meet up I'm going to start off with something simple — FizzBuzz (in future I'll be posting this a few days before BeerCamp to give people more time to think about it first).

The FizzBuzz problem can be stated as:

Print the numbers from 1 to 100, but if the number is divisible by three then print Fizz and if it's divisible by five print Buzz. For numbers divisible by both three and five print FizzBuzz.

The problem should be pretty simple to solve in any language. For example, here is the problem restated in Haskell:

fizzbuzz = map fizzbuzz' [1..100]
    where fizzbuzz' x
        | x `mod` 3 == 0 && x `mod` 5 == 0 = "FizzBuzz"
        | x `mod` 3 == 0 = "Fizz"
        | x `mod` 5 == 0 = "Buzz"
        | otherwise = show x

This four clause implementation is the simplest (for some values of simple anyway) and is what I would expect most people to write the equivalent of when they first implement it. The thing about it though is that the tests are duplicated as are the words Fizz and Buzz.

The first part of the puzzle is to refactor the code so that each test is done only once for each number and that the strings Fizz and Buzz only appear once. Does this refactoring make the code better or worse? How far can you take it before the code is certainly worse?

Recently I've become much more interested in design issues and how they are effected by the programming languages we use. I've been working a lot in C++, Python and JavaScript and I've continued to experiment with Haskell. The thing with design is that if you don't have choices you aren't designing anything, you're just doing things. In order to have choices you need to know lots of ways of doing things, and it's probably best to explore these alternatives in a setting away from production code. This is the motivation for the exercises — to explore how the same thing can be written in different to try to see which are the better ways of doing it.

How testable is the Haskell version? How would your program change in order to be able to add tests (if you didn't do that already)?

This means that issues such as testability and maintainability are very relevant to this — it isn't about coming up with the shortest or the fastest solution. It's about learning how things trade off between different options and there's enough good developers at BeerCamps to make for what I think should be some very interesting discussions. I will try to summarise these discussions the weekend after a BeerCamp and post to my blog here.

The problem parameters are hard coded — the divisible by three/five rules and the output strings for example — is it appropriate to try to parametrise them? How can they be parametrised? Is there a distinction between parametrising in the source code or by the user at runtime?

If you can't make BeerCamp then please get involved in the discussion anyway. Feel free to post in the forums on this site (or any aggregators it might turn up on). Feel free to have your say on your own blog too (I should be able to find them via Technorati), and if you feel more comfortable writing in some other language (like Thai) that's cool too.

(I'm not sure that my commenting system is really all that suitable for others to post source code though, something I'll have to think of a solution for. Putting four spaces before each line of code should work, but if you are using a language which makes use of square brackets you'll need to put a space after the opening one or it'll be interpreted as a link — probably not what you want, i.e. [ whatever ], not [whatever].)