Forum: Ruby FizzBuzz (#126)

Announcement (2017-05-07): is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see and for other Rails- und Ruby-related community platforms.
4299e35bacef054df40583da2d51edea?d=identicon&s=25 James Gray (bbazzarrakk)
on 2007-06-07 14:48
(Received via mailing list)
The discussion around this quiz touched on what the interviewer is
looking for when they ask this question.  Most people seem to agree that
least one goal is to establish that you are capable of writing some

The other item we assume the interviewers are searching for is some
degree of
cleverness.  The interesting thing is that we don't seem to agree on the
of cleverness.  Some feel you should provide a no-nonsense solution,
solving the
problem just as you would if it was a small part of your work for the
Others feel it's better to let your style flare a bit and show off
approaches to solving the problem.  The solutions covered both
approaches very

I'll start with my own, just because I can explain my thinking behind
Here's the code:

  #!/usr/bin/env ruby -w

  1.upto(100) do |i|
    if i % 5 == 0 and i % 3 == 0
      puts "FizzBuzz"
    elsif i % 5 == 0
      puts "Buzz"
    elsif i % 3 == 0
      puts "Fizz"
      puts i

The interesting part of this solution is what happened in my head.  When
I began
to code it up and realized the combined test would need to come first, I
experienced a brief moment of doubt in my logic and considered writing
tests.  After a calming breath, I convinced myself that this problem was
enough to not worry about them.  I was confident I was right, though
problem is about the upper limit of what I am comfortable doing without
and I might have caved-in easier under the pressure of a real interview.
For a
nice test-driven solution do look over Jason Merrill's response to the

There's nothing tricky in my code, of course.  I walk the numbers and
divisibility tests to decide what to print.  Many solutions took a very
approach with minor variations.  One such variation was to change the
divisibility check to:

  if n % 15 == 0                           # darrin kirby's code

  # ... or ...

  when num.dividable_by?(3*5): "fizzbuzz"  # Rene Koning's code

My opinion was that the two test approach was a more self-documenting
way to
code it up, but I found Rene's solution to be a good balance.

Looking back on my code now that I've examined over 70 solutions, I'm
aware of how much duplication there is in it.  I repeat the divisibility
and the calls to puts() in almost every branch.  A lot of solutions
DRYed that
code up.  Two common ways to do it were to pre-calculate the
divisibility tests
and to move puts() outside of the if/case statements.  Here's some code
Bill Guindon that shows off both tricks:

  (1..100).each do |x|
   m3 = x.modulo(3) == 0
   m5 = x.modulo(5) == 0

   puts case
     when (m3 and m5) then 'FizzBuzz'
     when m3 then 'Fizz'
     when m5 then 'Buzz'
     else x

You can see we're down to a single call to puts() here and The results
of the
tests are cached for convenient reuse.  I think that's an improvement.

We do still have duplication here too though, on a smaller scale.
First, the
test results are still checked multiple times.  That's not as bad as
redoing the
whole test, but it would be nice if it wasn't needed.  More importantly,
'Fizz' and 'Buzz' Strings are repeated in the 'FizzBuzz' String.
there is still room for DRYing things up.

Daniel Martin sent in a good example of code that only does each step

    x = ''
    x += 'Fizz' if i%3==0
    x += 'Buzz' if i%5==0
    puts(x.empty? ? i : x);

Here the output is built up piece by piece.  A divisible by three check
adds the
'Fizz' and divisible by five the 'Buzz'  If the number happens to be
by both they will be combined to yield 'FizzBuzz'  From there, a quick
check is
needed to see if the String is still empty?(), meaning that we should
output the
digit instead.

It's short code, easy to follow, and it doesn't give me any doubts about
functionality.  I think it's a solid approach to take.

Of course, if you're a fan of clever, don't miss MenTaLguY's lambda

My thanks to everyone who blew the quiz record out of the water time
I'll be looking for more boring problems now just because staying on top
of the
submissions was a real challenge.  ;)

Tomorrow we will show just how versatile Ruby programmers can be and
weave a few
This topic is locked and can not be replied to.