[QUIZ] FizzBuzz (#126)

my first solution:
(1..100).each do |n|
  print :Fizz if (n % 3) == 0
  print :Buzz if (n % 5) == 0
  print n if (n % 3) != 0 and (n % 5) != 0
  print "\n"
end

and my second one:
(1..100).each { |n| puts n % 3 == 0 ? n % 5 == 0 ? :FizzBuzz : :Fizz :
n % 5 == 0 ? :Buzz : n }

greets, paddor

···

2007/6/1, Ruby Quiz <james@grayproductions.net>:

The three rules of Ruby Quiz:

1. Please do not post any solutions or spoiler discussion for this quiz until
48 hours have passed from the time on this message.

2. Support Ruby Quiz by submitting ideas as often as you can:

http://www.rubyquiz.com/

3. Enjoy!

Suggestion: A [QUIZ] in the subject of emails about the problem helps everyone
on Ruby Talk follow the discussion. Please reply to the original quiz message,
if you can.

-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=

There has been some debate on the proper ways to screen programmers you intend
to hire. A common theory is that you really need to have the programmer write
some code for you to accurately gauge their skill. Exactly what to have them
write is another debate, but the blogosphere has recently been abuzz with this
question as a screener:

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

Pretend you've just walked into a job interview and been hit with this question.
Solve it as you would under such circumstances for this week's Ruby Quiz.

I'd probably want to do something a little clever but not anything
*too* unorthodox, so here's my solution:

def replace(n,list=[["FizzBuzz",15],["Buzz",5],["Fizz",3]])
  list.each { |r,m| return r if n % m == 0 }
  return n
end

puts (1..100).map { |e| replace(e) }

···

On 6/1/07, Ruby Quiz <james@grayproductions.net> wrote:

Pretend you've just walked into a job interview and been hit with this question.
Solve it as you would under such circumstances for this week's Ruby Quiz.

Ruby Quiz <james@grayproductions.net> writes:

Pretend you've just walked into a job interview and been hit with
this question. Solve it as you would under such circumstances for
this week's Ruby Quiz.

# Well, Mr. Martin, this is just a simple little question we ask all of
# our programming candidates. Let's see what you do with "FizzBuzz":

(1..100).each{|i|
  x = ''
  x += 'Fizz' if i%3==0
  x += 'Buzz' if i%5==0
  puts(x.empty? ? i : x);
}

# Okay, very straightforward. You know, I've never been an overly big
# fan of the question mark-colon operator. It always seemed to me one
# of the constructs in C most open to abuse.

···

#
# What's that? Oh, okay, so how would you eliminate that ?: in favor
# of something more Rubyish?

(1..100).each{|i|
  x = i
  x = 'Fizz' if i%3==0
  x += 'Buzz' if i%5==0 rescue x='Buzz'
  puts x;
}

# Well using "rescue" certainly does feel more Rubyish.
#
# It says here that you've done significant work with functional
# languages. Could you rewrite this to take advantage of higher order
# functions?

a = [proc{|x|x}, proc{|x|x}, proc{:Fizz}] * 5
a[4]=a[9]=proc{:Buzz}
a[14]=proc{:FizzBuzz}
(1..100).zip(a*9){|i,l|puts l[i]}

# Well that's rather cryptic, and I don't necessarily like the manual
# computation behind the indexes 4, 9, and 14. I'd prefer something
# that, like your first two solutions, combined the Fizz and Buzz so
# that the FIzzBuzz printed every fifteen spots is a natural
# consequence.

f = proc{'Fizz'}
b = proc{|x|x+'Buzz' rescue :Buzz}
i = proc{|x|x}
(1..100).zip([i,i,f]*99,[i,i,i,i,b]*99){|n,p,q|puts q[p[n]]}

# Uh... yes. In that I can see the two cycles, the 3-cycle and the
# 5-cycle, but I'm not sure that turned out as clear as I had hoped.
#
# I wonder if a hybrid approach where you used anonymous functions
# only for one of the two words is worth considering...

b=proc{|i,s|i%5==0?s+'Buzz':s rescue :Buzz}
puts (1..100).map{|i|b[i,i%3==0?'Fizz':i]}

# There's that ?: operator again.
#
# You know, you aren't really using arbitrary functions there. I wonder
# if lambda functions aren't overkill for this problem. What if you
# repeated the pattern where you showed the two cycles, but used simple
# strings instead?

$;='/'
(1..100).zip('//Fizz'.split*99,'////Buzz'.split*99) {|a|
puts(('%d%s%s'%a).sub(/\d+(?=\D)/,''))}

# Well, okay, you've shown that sometimes strings are not as easy to read
# as one might think.
#
# I noticed you using a regular expression there and I note that your
# resume shows extensive experience with regular expressions. That's a
# rather small example on which to judge your regular expression
# experience. Could you somehow make more use of regular expressions?

(1..100).map{|i|"#{i}\n"}.join.
  gsub(/^([369]?[0369]|[147][258]|[258][147])$/m,'Fizz\1').
  gsub(/\d*[50]$/m,'Buzz').gsub(/z\d+/,'z').display

# Let us never speak of this again.
#
# Well, Mr. Martin, I think you've shown technically what we're looking
# for. Tell me, do you golf?

puts (1..100).map{|a|x=a%3==0?'Fizz':'';x+='Buzz'if a%5==0;x.empty?? a:x}

# Uh, that

puts (1..100).map{|i|[i,:Buzz,:Fizz,:FizzBuzz][i%5==0?1:0+i%3==0?2:0]}

# Mr. Martin, that's not

puts (1..100).map{|i|i%15==0?:FizzBuzz:i%5==0?:Buzz:i%3==0?:Fizz:i}

# I, uh, hadn't meant that kind of golf.
# (Though, as an aside, you could save characters by using 1.upto(100)
# and by using <1 in place of ==0)
#
# However, these last few examples bring home a point I was worrying about
# before that we haven't really touched on yet - all of these have
# varying degrees of readability, yet Ruby is supposed to be an eminently
# readable language. How could you make this code more readable?

puts (1..100).map{|i|
  case i%15
  when 0 then :FizzBuzz
  when 5,10 then :Buzz
  when 3,6,9,12 then :Fizz
  else i
  end
}

# Well, that certainly is an improvement, though separating the "puts"
# from the rest of the logic might be slightly confusing and I'd prefer
# a more direct translation from the English program specification to
# the code.

(1..100).each {|i|
  if i%5==0 and i%3==0 then puts :FizzBuzz
  elsif i%5==0 then puts :Buzz
  elsif i%3==0 then puts :Fizz
  else puts i
  end
}

# Well now.
#
# Okay, are there any other tricks you have to show before we wrap this
# up?

h=Hash.new{|d,k|k>14?h[k%15]:nil}
h[0]=:FizzBuzz
h[3]=h[6]=h[9]=h[12]=:Fizz
h[5]=h[10]=:Buzz
puts (1..100).map{|i|h[i]||i}

# That looks rather familiar and similar to your first anonymous function
# solution. I think we've both had enough of this problem by now.
#
# Well, it's been nice talking to you, Mr. Martin, and I thank you for
# your interest in CompuGlobalMegaTech. We'll be in touch over the next
# few days with our decision.

--
s=%q( Daniel Martin -- martin@snowplow.org
       puts "s=%q(#{s})",s.to_a.last )
       puts "s=%q(#{s})",s.to_a.last

This is my solution from the time when I was considering this as a quiz.

#!/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"
   else
     puts i
   end
end

__END__

James Edward Gray II

···

On Jun 1, 2007, at 7:28 AM, Ruby Quiz wrote:

Pretend you've just walked into a job interview and been hit with this question. Solve it as you would under such circumstances for this week's Ruby Quiz.

I laughed at how silly the quiz is, and then I did my solution without
fully reading the spec. :frowning:

(1..100).each do |i|
  print i.to_s + ' '
  print 'Fizz' if i % 3 == 0
  print 'Buzz' if i % 5 == 0
  puts
end

I missed the 'instead of the number' part.

Ben

···

On 6/1/07, Ruby Quiz <james@grayproductions.net> wrote:

The three rules of Ruby Quiz:

1. Please do not post any solutions or spoiler discussion for this quiz until
48 hours have passed from the time on this message.

2. Support Ruby Quiz by submitting ideas as often as you can:

http://www.rubyquiz.com/

3. Enjoy!

Suggestion: A [QUIZ] in the subject of emails about the problem helps everyone
on Ruby Talk follow the discussion. Please reply to the original quiz message,
if you can.

-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=

There has been some debate on the proper ways to screen programmers you intend
to hire. A common theory is that you really need to have the programmer write
some code for you to accurately gauge their skill. Exactly what to have them
write is another debate, but the blogosphere has recently been abuzz with this
question as a screener:

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

Pretend you've just walked into a job interview and been hit with this question.
Solve it as you would under such circumstances for this week's Ruby Quiz.

--
Ben Atkin
ben@benatkin.com

One-liner?

(1..100).each{|i|puts
i%3==0?(i%5==0?"FizzBuzz":"Fizz"):(i%5==0?"Buzz":i)}

···

--
Posted via http://www.ruby-forum.com/.

#!/bin/env ruby

=begin
"Ruby Quiz" <james@grayproductions.net> wrote in message
news:20070601122814.XMOR28308.eastrmmtao105.cox.net@eastrmimpo02.cox.net...
..

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

Pretend you've just walked into a job interview and been hit with this
question.
Solve it as you would under such circumstances for this week's Ruby Quiz.

The task itself is quite boring, so I decided to imagine how
different programmers may try to pass the interview.
I hope we'll see what the recruiter may think.

Oh! And I played golf, just for fun, hope you will enjoy it too.
=end

···

##
# Q126 solution
# by Sergey Volkov
##

##
# job interview style
##
# Java programmer
def sol1 maxn=100
    for i in 1..maxn
        if i%3 == 0 && i%5 == 0
            puts "FizzBuzz"
        elsif i%3 == 0
            puts "Fizz"
        elsif i%5 == 0
            puts "Buzz"
        else
            puts i
        end
    end
end
puts '### TC1'
sol1 15

##
# Same as above,
# but the code is more manageable
def sol1a maxn=100
    for i in 1..maxn
        if i%3 == 0 && i%5 == 0
            s = "FizzBuzz"
        elsif i%3 == 0
            s = "Fizz"
        elsif i%5 == 0
            s = "Buzz"
        else
            s = i.to_s
        end
        puts s
    end
end
puts '### TC1a'
sol1a 15

##
# Lisp programmer
def sol2 maxn=100
    puts( (1..maxn).map{ |i|
        i2s=lambda{ |n,s|
            if (i%n).zero? : s else '' end
        }
        lambda{ |s|
            if s.empty? : i else s end
        }.call i2s[3,'Fizz'] + i2s[5,'Buzz']
    } )
end
puts '### TC2'
sol2 15

##
# 1 year of Ruby experience
def sol3 maxn=100
    1.upto(maxn){ |n|
        s = "Fizz" if (n%3).zero?
        (s||='') << "Buzz" if (n%5).zero?
        puts s||n
    }
end
puts '### TC3'
sol3 15

##
# Trying to get extra points for reusability..
class Fixnum
    def toFizzBuzz
        s = 'Fizz' if modulo(3).zero?
        s = "#{s}Buzz" if modulo(5).zero?
        s || to_s
    end
end
def sol4 maxn
    1.upto(maxn){ |n| puts n.toFizzBuzz }
end
puts '### TC4'
sol4 15

##
# Extra points for expandability
#.. who knows what else recruiters are looking for?

__END__

##
# Golf style
1.upto(?d){|i|puts ["#{x=[:Fizz][i%3]}Buzz"][i%5]||x||i}# 56
1.upto(?d){|i|x=[:Fizz][i%3];puts i%5<1?"#{x}Buzz":x||i}# 56
1.upto(?d){|i|i%3<1&&x=:Fizz;puts i%5<1?"#{x}Buzz":x||i}# 56

Arlighty! my first submission. If I ever get asked this at a job interview for, say, the local bookstore (i'm not exactly old enough to get what most people call a 'real' job), I'll be ready:

1.upto(?d) do |x|
   p 'fizzBuzz' if x % 3 == 0 && x % 5
   p 'fizz' if x % 3 == 0
   p 'buzz' if x % 5 == 0
   p x if x % 3 != 0
end

for those who wrote it in 58 chars..... I don't know what to say...
-------------------------------------------------------|
~ Ari
crap my sig won't fit

Here's my solution. It makes heavy use of the Ruby idiom of using the
&& and || operators to perform conditionals because a) they are short-
circuited and because b) && returns the right-hand-side when the left-
hand-side is a true value.

···

====
class Integer; def factor? n; self % n == 0; end; end

puts (1..100).map { |i| i.factor?(15)&&"FizzBuzz" || i.factor?
(3)&&"Fizz" || i.factor?(5)&&"Buzz" || i }

Eric

Are you interested in on-site Ruby training that uses well-designed,
real-world, hands-on exercises? http://LearnRuby.com

My solution, which is probably pretty similar to everyone else's
solution, but I didn't feel like being creative this weekend:

1.upto(100) do |i|
   puts case i % 15
      when 0 then "FizzBuzz"
      when 5, 10 then "Buzz"
      when 3, 6, 9, 12 then "Fizz"
      else i
   end
end

Attached are my 7 attempts. Some are ok, some are crap. No golfing.

fb_0.rb (313 Bytes)

fb_4.rb (366 Bytes)

fb_2.rb (320 Bytes)

fb_1.rb (296 Bytes)

fb_5.rb (329 Bytes)

fb_6.rb (426 Bytes)

fb_3.rb (395 Bytes)

···

--
Jesse Merriman
jessemerriman@warpmail.net
http://www.jessemerriman.com/

Interesting quiz, as usual.

I don't really have experience applying for jobs, but my own
experience tells me that when writing code, you should write it for
others to read it, change it, manage it and/or throw it away.

The first question that jumps into my mind is: why would a job
interviewer wanted me to write me such a program? What the heck is a
'FizzBuzz'?

Probably is a company secret. To me, it looks like a little useless
noise coming from somewhere.

# Class that takes numbers and transforms them into a symbol
# specified for the user

class UselessSoundMaker

  attr_accessor :sounds

  def initialize(args)
    @sounds = args
  end

  def add_sounds(args)
    @sounds.update(args)
  end

  def display(range = 1..100)
    for number in range
      if (multiples = @sounds.keys.select{|m| number % m == 0}).empty?
        puts number
      else
        puts multiples.sort.collect{|m| @sounds[m]}.join
      end
    end
  end

end

fizzbuzz = UselessSoundMaker.new(3 => 'Fizz', 5 => 'Buzz')
fizzbuzz.display

foobar = UselessSoundMaker.new(3 => 'Foo', 4 => 'Bar', 5 => 'Baz')
foobar.display(1..50)

beepbeep = UselessSoundMaker.new(10 => "\a")
beepbeep.display(1..100)

Thanks again for the quizes.

Ruben Medellin.

···

On Jun 1, 7:28 am, Ruby Quiz <j...@grayproductions.net> wrote:

The three rules of Ruby Quiz:

__________________________________________

Dictionary is the only place that success comes before work. - Vince
Lombardi

I'll add my solutions to the thundering horde. My first solution was
moderately clever:

puts
(1..100).map{|n|[[3,'fizz'],[5,'buzz']].inject(n){|s,a|s.is_a?(Fixnum)?s
=a[1]:s+=a[1] if n%a[0]==0;s}}

then I tried to use as few characters as possible:

puts (1..100).map{|n|n%15==0?:fizzbuzz:n%5==0?:buzz:n%3==0?:fizz:n}
puts (1..100).map{|n|n%15>0?n%5>0?n%3>0?n:'fizz':'buzz':'fizzbuzz'}

- donald

Here is my solution:

http://pastie.caboo.se/68127

for i in 1..100
mod3 = (i % 3 == 0)
mod5 = (i % 5 == 0)

print "Fizz" if mod3
print "Buzz" if mod5
print i if !mod3 && !mod5

puts ""
end

Dan Finnie

Ruby Quiz wrote:

···

The three rules of Ruby Quiz:

1. Please do not post any solutions or spoiler discussion for this quiz until
48 hours have passed from the time on this message.

2. Support Ruby Quiz by submitting ideas as often as you can:

http://www.rubyquiz.com/

3. Enjoy!

Suggestion: A [QUIZ] in the subject of emails about the problem helps everyone
on Ruby Talk follow the discussion. Please reply to the original quiz message,
if you can.

-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=

There has been some debate on the proper ways to screen programmers you intend
to hire. A common theory is that you really need to have the programmer write
some code for you to accurately gauge their skill. Exactly what to have them
write is another debate, but the blogosphere has recently been abuzz with this
question as a screener:

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

Pretend you've just walked into a job interview and been hit with this question.
Solve it as you would under such circumstances for this week's Ruby Quiz.

I am sure I just submitted this with a lengthy explanation but it
didn't appear in the list ??? So here it is again with no explanation
except that it minimizes method calls as much as possible by
avoiding modulo operation and maintaining separate counters.

f = 3
b = 5

for i in 1..100 do
     if i == f
         if i == b
             puts "fizzbuzz"
             f += 3
             b += 5
         else
             puts "fizz"
             f += 3
         end
     elsif i == b
         puts "buzz"
         b += 5
     else
         puts i
     end
end

After completing my Ruby Quiz submission, I decided to implement FizzBuzz in Mathematica. Here is the first version that I wrote.

f[x_] := Print["FizzBuzz"] /; Mod[x, 15] == 0
f[x_] := Print["Buzz"] /; Mod[x, 5] == 0
f[x_] := Print["Fizz"] /; Mod[x, 3] == 0
f[x_] := Print[x]
f /@ Range[100];

I think this example pretty well gives the flavor of Mathematica. Note that no explicit flow control is needed. Of course, Mathematica, like Ruby, allows one to write FizzBuzz in many ways, including some that would look much more procedural and others that are more functional. Here is an example of the latter.

MapThread[(f[z_] := Print[#1] /; Mod[z, #2] == 0) &,
  {{"FizzBuzz", "Buzz", "Fizz"}, {15, 5, 3}}];
f[x_] := Print[x]
f /@ Range[100];

In this second example, the MapThread generates three lines of code equivalent to the first three lines of the first example.

I apologize to anyone who finds this off topic post distracting, but I am hoping at least some readers of mailing list will find it interesting to see FizzBuzz in a language very different both from Ruby and all the well-known static, procedural languages.

Regards, Morton

Quiz 126 is now the most popular Ruby Quiz ever. Quiz 84 was the previous champion. All Rubyists will grasp the significance of 126 - 84 = 42 :slight_smile:

Ain't numerology fun?

Regards, Morton

My solution that I'd submit in an interview:

1.upto(100) do |i|
  buffer = i % 3 == 0 ? "Fizz" : nil
  buffer = buffer.to_s + "Buzz" if i % 5 == 0
  p buffer || i
end

--RYAN

I do not think there is a lot of room for cleverness in the FizzBuzz
problem. (Actually, I hope I am wrong and we see lots more
suggestions for Extra Fun like Peter's.) My understanding is that
FizzBuzz was intended to screen out candidates that could *not* come
up with working code in a few minutes.

Regards,

Paul.

···

On Jun 1, 9:51 am, Hans Fugal <fug...@zianet.com> wrote:

Ruby Quiz wrote:
> There has been some debate on the proper ways to screen programmers you intend
> to hire. A common theory is that you really need to have the programmer write
> some code for you to accurately gauge their skill. Exactly what to have them
> write is another debate, but the blogosphere has recently been abuzz with this
> question as a screener:

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

> Pretend you've just walked into a job interview and been hit with this question.
> Solve it as you would under such circumstances for this week's Ruby Quiz.

Done, 4 times over. Not a bad quiz though my answers will probably be
considered boring and would be denounced by the fools using this tactic
to hire people as "unimaginative" or "lacking creativity and whizbang
problem-solving skills".

I feel compelled to point out that it was Microsoft who started this
whole mess, and they quickly figured out it was selecting the wrong
people and they don't do it anymore. But the cat's out of the bag, and
now every wannabe shop thinks that's the way to find smart people. It's
not, it's the way to find people who are good at solving puzzles under
pressure, and in the worst case to find people who are good at finding
ridiculously clever (but unreadable/unmaintainable) answers to puzzles
under pressure.

As we all know, good software development is not about solving little
puzzles. It's about reasoning about problems large and small and finding
the most obvious and readable solution (and sometimes optimizing the
inner loop).

Maybe I would try this in a job interview. I might state the problem and
say: "this is not a trick question nor hard - just write the code they
way you normally would." If they write the boring answer, they get
points in my book. If they write some clever answer, they get demerits.
If they can't write code at all, and I didn't realize they wouldn't be
able to, I go sit in a corner and pout.

Fizzbuzz has nothing with the Microsoft "How many Ping Pong balls fit
in a Jumbojet" questions. It got a lot of feedback at
http://www.codinghorror.com/blog/archives/000781.html .
Another one used it to find out if CS graduates can program.

···

2007/6/1, Hans Fugal <fugalh@zianet.com>:

Done, 4 times over. Not a bad quiz though my answers will probably be
considered boring and would be denounced by the fools using this tactic
to hire people as "unimaginative" or "lacking creativity and whizbang
problem-solving skills".

I feel compelled to point out that it was Microsoft who started this
whole mess, and they quickly figured out it was selecting the wrong
people and they don't do it anymore. But the cat's out of the bag, and
now every wannabe shop thinks that's the way to find smart people. It's
not, it's the way to find people who are good at solving puzzles under
pressure, and in the worst case to find people who are good at finding
ridiculously clever (but unreadable/unmaintainable) answers to puzzles
under pressure.

As we all know, good software development is not about solving little
puzzles. It's about reasoning about problems large and small and finding
the most obvious and readable solution (and sometimes optimizing the
inner loop).

Maybe I would try this in a job interview. I might state the problem and
say: "this is not a trick question nor hard - just write the code they
way you normally would." If they write the boring answer, they get
points in my book. If they write some clever answer, they get demerits.
If they can't write code at all, and I didn't realize they wouldn't be
able to, I go sit in a corner and pout.