Groovy Fizz and Buzz

The FizzBuzz programming interview question raised it's head again. I've managed to resist the temptation to implement it in any languages so far. Until this morning that is...

So I fired up the Groovy Console and played a little. A nice feature of the console is that it displays a history of the scripts it ran. This allows me to present an evolution of my FizzBuzz program.

I first started with a rather naive implementation:

(1..100).each { 
  def out = "" 
  if ((it % 3) == 0) { out += "Fizz" } 
  if ((it % 5) == 0) { out += "Buzz" } 
  if (out == "" ) { out = it } 
  println out
}

Not bad for something that I came up with in about 10 minutes. It doesn't really take advantage of Groovy's features though. So I refined it a bit by using the ternary operator:

(1..100).each {
  def out = (it % 3) == 0 ? "Fizz" : ""
  out += (it % 5) == 0 ? "Buzz" : ""
  println (out == "" ? it : out)
}

This is a slight improvement over the first version. I still didn't feel that this was Groovy enough for me. I decided to play with the List collect method. This applies a closure to all items in a collection. The first pass was the following code segment:

println ((1..100).collect {
  def out = (it % 3) == 0 ? "Fizz" : ""
  out += (it % 5) == 0 ? "Buzz" : ""
  out == "" ? it : out
})

This ended up printing the list returned by the collect method. Really close, but not quite what I was hoping for. After all, the challenge is to print the results, not quite a string representation of a list. It was easy then to go from the code above to the code below:

(1..100).collect {
  def out = (it % 3) == 0 ? "Fizz" : ""
  out += (it % 5) == 0 ? "Buzz" : ""
  out ?: it
}.each { println it }

This printed the list just like the first pass. It's definitively Groovier (in my opinion) than the original implementation. It still does fall short of the capabilities of Groovy.

So here's my final implementation:

(1..100).collect {
     ((it % 3) == 0 ? "Fizz" : "") << ((it % 5) == 0 ? "Buzz" : "") ?: it
}.each { println it }

This takes full advantage of Groovy's power. It is a little harder to read, which is a downside. It does take full advantage of many of Groovy's powerful features:

  1. A range to generate the list of numbers to process. Ranges return an iterator that iterates from the start of the range to the end of the range.
  2. The collect method which applies a closure to each item in the collection (or iterator) and returns the results as a list.
  3. The each method, which iterates through a list and applies a closure to it. It returns the collection that it iterated through.
  4. Closures, which are implemented quite well in Groovy.
  5. Operator overloading. The << operator is overloaded on the String class to concatenate two Strings together.
  6. The brand new Elvis operator (?:) which returns the alternate value if the expression evaluates to false.
  7. Groovy returns the last expression of a block as the result of the block. This includes closures and methods.

I do think that I'll incorporate this question in future interviews. It has quite a few interesting subtleties and implementations that are only rivaled by the Singleton pattern. I guess that the last group of interviewees got it a little easier...