[QUIZ] FizzBuzz (#126)

R

Ryan Leavengood

My first, obvious solution:

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

Trying to reduce the redundant ifs:

(1..100).each do |i|
s = ''
s << "Fizz" if (i % 3 == 0)
s << "Buzz" if (i % 5 == 0)
puts(s == '' ? i : s)
end

The above seems unique among the solutions I've read so far.

Ryan
 
J

James Edward Gray II

This solution cracked me up, but there is a typo in it...

puts '59'
puts 'FizzBuzz
puts '61'

The middle line there is missing a quote. ;)

James Edward Gray II
 
P

paddor

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
 
G

Gregory Brown

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) }
 
B

Bill Guindon

This solution cracked me up, but there is a typo in it...



The middle line there is missing a quote. ;)

But would you hire him (minus the typo)? I'd be a bit worried that
he'd shown up for a job interview with a hangover ;)
 
D

Daniel Martin

Ruby Quiz said:
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}

# 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}

# 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.
 
J

James Edward Gray II

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

They would be a fool not to hire you. ;)

James Edward Gray II
 
R

Robert Dober

This is for a higher position than sheer Software Engineer, pah...

puts( %w{ Fizz Buzz FizzBuzz } * 33 + [*1..100].reject{|n|
(n%3*n%5).zero? }.sort_by{ |n| exercise_is_left_to_the_reader n
}[0..99].join("\n") )
 
J

James Edward Gray II

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.

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
 
B

Ben Atkin

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

(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


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

Rick DeNatale

This solution cracked me up, but there is a typo in it...



The middle line there is missing a quote. ;)

The 'safer' way to do this approach might be something like:

%w{1 2 Fizz 4 Buzz Fizz 7 8 Fizz Buzz 11 Fizz 13 14 FizzBuzz
16 17 Fizz 19 Buzz Fizz 22 23 Fizz Buzz 26 Fizz 28 29 FizzBuzz
31 32 Fizz 34 Buzz Fizz 37 38 Fizz Buzz 41 Fizz 43 44 FizzBuzz
46 47 Fizz 49 Buzz Fizz 52 53 Fizz Buzz 56 Fizz 58 59 FizzBuzz
61 62 Fizz 64 Buzz Fizz 67 68 Fizz Buzz 71 Fizz 73 74 FizzBuzz
76 77 Fizz 79 Buzz Fizz 82 83 Fizz Buzz 86 Fizz 88 89 FizzBuzz
91 92 Fizz 94 Buzz Fizz 97 98 Fizz Buzz
}.each {|x| puts x}

Oops now I have 11 solutions! <G>



--
Rick DeNatale

My blog on Ruby
http://talklikeaduck.denhaven2.com/

IPMS/USA Region 12 Coordinator
http://ipmsr12.denhaven2.com/

Visit the Project Mercury Wiki Site
http://www.mercuryspacecraft.com/
 
D

dblack

Hi --

The 'safer' way to do this approach might be something like:

%w{1 2 Fizz 4 Buzz Fizz 7 8 Fizz Buzz 11 Fizz 13 14 FizzBuzz
16 17 Fizz 19 Buzz Fizz 22 23 Fizz Buzz 26 Fizz 28 29 FizzBuzz
31 32 Fizz 34 Buzz Fizz 37 38 Fizz Buzz 41 Fizz 43 44 FizzBuzz
46 47 Fizz 49 Buzz Fizz 52 53 Fizz Buzz 56 Fizz 58 59 FizzBuzz
61 62 Fizz 64 Buzz Fizz 67 68 Fizz Buzz 71 Fizz 73 74 FizzBuzz
76 77 Fizz 79 Buzz Fizz 82 83 Fizz Buzz 86 Fizz 88 89 FizzBuzz
91 92 Fizz 94 Buzz Fizz 97 98 Fizz Buzz
}.each {|x| puts x}

Or:

puts %w{ 1 2 Fizz 4 ... }

:)


David

--
Q. What is THE Ruby book for Rails developers?
A. RUBY FOR RAILS by David A. Black (http://www.manning.com/black)
(See what readers are saying! http://www.rubypal.com/r4rrevs.pdf)
Q. Where can I get Ruby/Rails on-site training, consulting, coaching?
A. Ruby Power and Light, LLC (http://www.rubypal.com)
 
D

Drew Olson

One-liner?

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

S.Volkov

Robert Dober said:
If I want the job ;)

X = [ %w{FizzBuzz} + %w{Fizz} * 4 ]
Y = %w{Buzz}
(1..100).each do |n|
puts( X[n%3][n%5]) rescue puts( Y[n%5]||n )
end
Robert, you are not kind to guys who will maintain your code.
Do you want the job or demonstration of your smartness?
It's could be great for small startup doing R&D,
but not for enterprise-like development.
imho: in any situation: KISS!
 
A

Ari Brown

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
 
A

Ari Brown

Ok, minor change to my prog - at least it will cut away 10 chars though.

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


--------------------------------------------|
If you're not living on the edge,
then you're just wasting space.
 
J

Joshua Ballanco

Brian said:
^^
Why the ,x here? x is locally scoped within the block anyway, and it
works
without it.

Yeah, I realized that shortly after posting this...still, I'm over by
2...

Oh, and just to clarify my earlier suggestion of a 56 chr random code
generator...my rough guestimate is that it would take all the computers
on the earth working together about 10^80 times the age of the universe
to find the solution...

...you know, just so all you golfers don't feel so bad.

-Josh
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,780
Messages
2,569,609
Members
45,253
Latest member
BlytheFant

Latest Threads

Top