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”.

Thursday, February 2, 2012

Buzz 10 - How Many Times?

I'm going to be changing up my plan for Buzz entries.  I had intended on writing 500-1500 essays tangentially related to the FizzBuzz at hand (much like my tiny e-book on Amazon) but I see several problems with it. First, it can ruin the natural progression of solutions if I hold out one solution for a particular post I have planned.  Second, it will ruin the the general feel of this blog, going from technical to random life experiences and then back.  Third, writing that much text on a deadline is kinda hard with my current life balance.  Really, should 1st graders have homework?  Even if it is reading with a parent 20 minutes a night?

So here is the new Buzz plan... for each Buzz I will revisit a language introduced in a previous Fizz entry, and re-work a number entry not in that language using some of the unique features of the language.  For this first entry the selection is limited, but actually relevant to the current numeric theme, especially since Groovy has so many ways to do repitition.

100 times {
  int i = it+1
  if ((i % 3 == 0) && (i % 5 == 0)) {
    println "FizzBuzz"
  } else if (i % 3 == 0) {
    println "Fizz"
  } else if (i % 5 == 0) {
    println "Buzz"
  } else {
    println i
  }
}

Lines one and two are the focus for this post, because the rest of it is a simple transliteration to standard Groovy.

On first reading, it does what it says. Repeat the enclosed block 100 times. But in the syntax sugar and details of the API are some common assumptions. First, what the current count is matters, but there is no explicit variable for that. Each closure without an argument block gets a single variable it that you don't need to declare and just exists. Kind of like this in methods. (And when is some programming language going to introduce that?)

The next assumption is what number to count from. You would think that counting from 1 would be sensible. But Groovy uses zero based arrays, like nearly all popular languages, so instead it starts all couting from zero. Line 2 is an optimization so we don't have to extend our math into the rest of the method.

The rest is pure syntactic sugar. When a symbol that could be a method trails an object with no punctuation it is presumed to be a method call in Groovy. And when a single closure follows a method call, whether or not it is in the argument list, it is added to the argument list of the method. The integer 100 is boxed up to a java.lang.Integer class. And via the Meta-Object-Protocol we can graft in a random times method onto the Ingeger class even though it doesn't exist in the plain JDK.

The end result is something that looks a little bit more like a spoken sentence, but not too close.

No comments:

Post a Comment