[QUIZ] FizzBuzz (#126)

R

Robert Dober

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.
That could be discussed, but this is a small entity, from my
experience maintenance nightmares come from bad design and code
dependencies. There would be some nice unit tests and if the
maintainer cannot figure out this code she can rewrite it.
Do you want the job or demonstration of your smartness?
Would I like a job that does not fit my style - unless unemployed.

This is not very smart a solution, it reflects some features of Ruby,
after all they are hiring a Ruby developer not a C or Perl developer.
It's could be great for small startup doing R&D,
but not for enterprise-like development.
imho: in any situation: KISS!

This is strong an expression, I will not take offense, others might.

Cheers
Robert
 
P

Pieter V.

------=_Part_15326_24970199.1180895635320
Content-Type: text/plain; charset=UTF-8; format=flowed
Content-Transfer-Encoding: 7bit
Content-Disposition: inline

Two quiz solutions here - one as per my interview situation, and one
for golfing.

So: much like Marcel Proust biting into a madelaine, when I read this quiz on
Friday I had a rush of old memories. I have never heard of fizzbuzz being
used as a recruitment technique before, however, I am familiar with it
because back in high school we played it as a drinking game. If we were
feeling particularly hardcore we would also add in 'Bang' for multiples of 7.
I had as much as forgotten about fizzbuzz as I haven't though about it in
over twelve years or so...

Anyway, I have deviated from the official spec in a few ways here. First of
all, I saw no reason to stop at 100, so my solution will print results for
any user-specified 'n'. Rather than golfing, which I am no good at, I decided
to go with an obvious solution.

The second deviation is that because the solution is fairly short (ie: about a
paragraph) I thought it would be interesting to write solutions in a few
other languages as a point of comparison. To that end I also wrote solutions
in Python, Lua, Scheme, and plain old C. Hopefully you can forgive me some
off-topicness for posting these as well.

On with the code:

# fizz.rb
1.upto(ARGV[0].to_i) do |n|
if n % 15 == 0
print "FizzBuzz "
elsif n % 5 == 0
print "Buzz "
elsif n % 3 == 0
print "Fizz "
else print "#{n} "
end
end
puts

# fizz.py
import sys
for n in range(1,int(sys.argv[1])+1):
if n % 15 == 0:
sys.stdout.write("FizzBuzz ")
elif n % 3 == 0:
sys.stdout.write("Fizz ")
elif n % 5 == 0:
sys.stdout.write("Buzz ")
else: sys.stdout.write("%i " % n)
print

-- fizz.lua
for n=1,arg[1] do
if n % 15 == 0 then
io.write("FizzBuzz ")
elseif n % 3 == 0 then
io.write("Fizz ")
elseif n % 5 == 0 then
io.write("Buzz ")
else
io.write(n .. " ")
end
end
print()

/* fizz.c */
#include <stdio.h>

int main(int argc, char *argv[]) {
int i;
for (i = 1; i <= atoi(argv[1]); i++) {
if (i % 15 == 0)
printf("%s ", "FizzBuzz");
else if (i % 3 == 0)
printf("%s ", "Fizz");
else if (i % 5 == 0)
printf("%s ", "Buzz");
else
printf("%i ", i);
}
printf("\n");
return 0;
}

;;; fizz.scm
(define (fizz x)
(define (mod5? n)
(if (eq? (modulo n 5) 0) #t #f))
(define (mod3? n)
(if (eq? (modulo n 3) 0) #t #f))
(define (fizz-iter n x)
(cond
((> n x) (newline) #t)
((and (mod3? n) (not (mod5? n))) (display "Fizz ")
(fizz-iter (+ n 1) x))
((and (mod5? n) (not (mod3? n))) (display "Buzz ")
(fizz-iter (+ n 1) x))
((and (mod5? n) (mod3? n)) (display "FizzBuzz ")
(fizz-iter (+ n 1) x))
(else (display n) (display " ")
(fizz-iter (+ n 1) x))))
(fizz-iter 1 x))

cheers,
-d

------=_Part_15326_24970199.1180895635320
Content-Type: application/octet-stream; name=fizzbuzz.rb
Content-Transfer-Encoding: base64
X-Attachment-Id: f_f2hupx9d
Content-Disposition: attachment; filename="fizzbuzz.rb"

IyEvdXNyL2xvY2FsL2Jpbi9ydWJ5CgokbGFzdCA9IDEwMAoKKDEuLiRsYXN0KS5lYWNoIGRvIHxu
dW18CiAgaWYgKG51bSAlIDMpID09IDAgfHwgKG51bSAlIDUpID09IDAKICAgIHByaW50ICJGaXp6
IiBpZiAobnVtICUgMykgPT0gMAogICAgcHJpbnQgIkJ1enoiIGlmIChudW0gJSA1KSA9PSAwCiAg
ICBwdXRzCiAgZWxzZQogICAgcHV0cyBudW0KICBlbmQKZW5kCg==
------=_Part_15326_24970199.1180895635320
Content-Type: application/octet-stream; name=fizzbuzz-2.rb
Content-Transfer-Encoding: base64
X-Attachment-Id: f_f2hupyqs
Content-Disposition: attachment; filename="fizzbuzz-2.rb"

MS51cHRvKD9kKXt8bnxwdXRzIG4lMTU8MT86Rml6ekJ1eno6biUzPDE/OkZpeno6biU1PDE/OkJ1
eno6bn0K
------=_Part_15326_24970199.1180895635320--
 
T

Todd Benson

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

Just build a self-sustaining computer complete with time-travel
capabilities, programmed to reboot a few eons every once and a while,
and, poof there you go ... an instant solution to any NP problem! I
wonder if Turing thought of such things.
 
S

S.Volkov

Robert Dober said:
That could be discussed, but this is a small entity, from my
experience maintenance nightmares come from bad design and code
dependencies.
Sure, you are right.
But please don't forget, that 'small entity' can cause 'big problem' if
muliplyed by huge number.
Given 100 average-level programmers, how many will be able to expand your
solution
to handle addition of one more multiplyer, say 7-Gozz?
Enterprise managers face luck of experienced programmers to execute routine
maintenance tasks,
so simple solution for simple task is a _must_.
This is not very smart a solution, it reflects some features of Ruby,
after all they are hiring a Ruby developer not a C or Perl developer.
I didn't say it was smart solution :)
This is strong an expression, I will not take offense, others might.
I'm terrybly sorry, no offense was intended (I forgot to mention this
specifically in first place)!
ashamed,
Sergey Volkov
 
R

Rick DeNatale

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

Ah, but another approach which might get there faster is to start with
a working small solution and then randomly mutate it until a shorter
correct solution was found.
 
R

Robert Dober

Sure, you are right.
But please don't forget, that 'small entity' can cause 'big problem' if
muliplyed by huge number.
Given 100 average-level programmers, how many will be able to expand your
solution
to handle addition of one more multiplyer, say 7-Gozz?
Enterprise managers face luck of experienced programmers to execute routine
maintenance tasks,
so simple solution for simple task is a _must_.
But what is simple?
(1..100).each{ |x|
print "Fuzz" if x%3 ==0
print "Bizz" if x%5
print x unless x%3*y%5==0
puts ""
}
Is this simple?
Maybe you are right about the _must_ but then I feel that you are
wrong about the language.
I feel very *strongly* that Ruby is not a language for such code....
Let us maybe take a break, wait for James' resume and what other think
about this and than we might find a better understanding of this.
Boy who said this was a simple Quiz ;)
I didn't say it was smart solution :)
Hmm I do ;)
I'm terrybly sorry, no offense was intended (I forgot to mention this
specifically in first place)!
ashamed,
No that is exaggerated of course as I said no offense taken.
Sergey Volkov
Do you like Star Trek?
Reminds me of the famous dialog between bones and Spock:
I am Spock you are bones ;)
Robert
 
E

Eric I.

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
 
R

Robert Dober

Sergey it is your fault if I cannot sleep ;), is this more readable ?

module Enumerable
def change(to, &blk)
map{ |x| blk.call(x) ? to : x }
end
end # module Enumerable

puts (1..100).change:)FizzBuzz){ |x| x%15 == 0 }.change:)Fizz){ |x|
x%3 == 0 rescue false}.change:)Buzz){ |x| x%5 == 0 rescue false }
 
S

Sergey Volkov

----- Original Message -----
From: "Robert Dober" <[email protected]>
To: "ruby-talk ML" <[email protected]>
Sent: Sunday, June 03, 2007 6:38 PM
Subject: Re: [QUIZ] FizzBuzz (#126)

Sergey it is your fault if I cannot sleep ;), is this more readable ?
relax, Robert, nobody hurt :)
module Enumerable
def change(to, &blk)
map{ |x| blk.call(x) ? to : x }
end
end # module Enumerable

puts (1..100).change:)FizzBuzz){ |x| x%15 == 0 }.change:)Fizz){ |x|
x%3 == 0 rescue false}.change:)Buzz){ |x| x%5 == 0 rescue false }
hard to make formal conclusions - there are no formal requirements,
nor context is well defined, I can share my own opinion and potential
concerns only:

- yes, indeed, this solution is more readable,
compared to your Array-nested-tricky-indexed original solution;
- clear functional decomposition simplifies understanding, maintenance;
- it is easily expandable thanks to chain processing;
btw: I prefer different name for Enumerable method, ex: substitute_if;

Not so attractive in this solution:
- run-time/memory inefficient: each item is generates 4 times;
- memory inefficient: generates and stores in memory 4*original array
(ex: not well suited for 10**9 length array);
- can not be adopted for stream processing (read - process - print);
- 'rescue' is for exceptional processing, should be avoided in normal
control flow;

Sergey Volkov
 
M

Matthew Moss

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
 
J

Jesse Merriman

--Boundary-00=_dZ3YGrWwbOouLYM
Content-Type: Multipart/Mixed;
boundary="Boundary-00=_dZ3YGrWwbOouLYM"

--Boundary-00=_dZ3YGrWwbOouLYM
Content-Type: text/plain;
charset="utf-8"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline

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


--
Jesse Merriman
(e-mail address removed)
http://www.jessemerriman.com/

--Boundary-00=_dZ3YGrWwbOouLYM
Content-Type: application/x-ruby;
name="fb_0.rb"
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment;
filename="fb_0.rb"

#!/usr/bin/env ruby
# Ruby Quiz 126: FizzBuzz
# fb_0.rb

Fizz = 3
Buzz = 5
FizzBuzz = Fizz * Buzz

(1..100).each do |x|
if (x % FizzBuzz).zero? then puts 'FizzBuzz'
elsif (x % Fizz).zero? then puts 'Fizz'
elsif (x % Buzz).zero? then puts 'Buzz'
else puts x
end
end

--Boundary-00=_dZ3YGrWwbOouLYM
Content-Type: application/x-ruby;
name="fb_4.rb"
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment;
filename="fb_4.rb"

#!/usr/bin/env ruby
# Ruby Quiz 126: FizzBuzz
# fb_4.rb

Fizz = 3
Buzz = 5
FizzBuzz = Fizz * Buzz

class Integer
def fizzbuzz
if (self % FizzBuzz).zero? then 'FizzBuzz'
elsif (self % Fizz).zero? then 'Fizz'
elsif (self % Buzz).zero? then 'Buzz'
else to_s
end
end
end

(1..100).each { |x| puts x.fizzbuzz }

--Boundary-00=_dZ3YGrWwbOouLYM
Content-Type: application/x-ruby;
name="fb_2.rb"
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment;
filename="fb_2.rb"

#!/usr/bin/env ruby
# Ruby Quiz 126: FizzBuzz
# fb_2.rb

Fizz = 3
Buzz = 5

arr = Array.new(100) do |i|
x = i + 1
if (x % Fizz).zero?
if (x % Buzz).zero? then 'FizzBuzz'
else 'Fizz' end
elsif (x % Buzz).zero? then 'Buzz'
else x end
end

arr.each { |e| puts e }

--Boundary-00=_dZ3YGrWwbOouLYM
Content-Type: application/x-ruby;
name="fb_1.rb"
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment;
filename="fb_1.rb"

#!/usr/bin/env ruby
# Ruby Quiz 126: FizzBuzz
# fb_1.rb

Fizz = 3
Buzz = 5

(1..100).each do |x|
if (x % Fizz).zero?
if (x % Buzz).zero? then puts 'FizzBuzz'
else puts 'Fizz' end
elsif (x % Buzz).zero? then puts 'Buzz'
else puts x end
end

--Boundary-00=_dZ3YGrWwbOouLYM
Content-Type: application/x-ruby;
name="fb_5.rb"
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment;
filename="fb_5.rb"

#!/usr/bin/env ruby
# Ruby Quiz 126: FizzBuzz
# fb_5.rb

class Integer
def fizzbuzz arr, str
arr.each_with_index do |x, i|
arr = ((i+1) % self).zero? ? str : x
end
end
end

arr = (1..100).to_a
3.fizzbuzz arr, 'Fizz'
5.fizzbuzz arr, 'Buzz'
15.fizzbuzz arr, 'FizzBuzz' # Must be last.

arr.each { |x| puts x }

--Boundary-00=_dZ3YGrWwbOouLYM
Content-Type: application/x-ruby;
name="fb_6.rb"
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment;
filename="fb_6.rb"

#!/usr/bin/env ruby
# Ruby Quiz 126: FizzBuzz
# fb_6.rb

FB = lambda { |mod, str| lambda { |x| (x % mod).zero? ? str : x } }
Fizz = FB[3, 'Fizz']
Buzz = FB[5, 'Buzz']
FizzBuzz = FB[15, 'FizzBuzz']

# Note that this wouldn't work if the numbers to_s'd got longer than their
# fizz-buzzed strings.
(1..100).each do |x|
puts([Fizz[x], Buzz[x], FizzBuzz[x]].max do |a,b|
a.to_s.length <=> b.to_s.length
end)
end

--Boundary-00=_dZ3YGrWwbOouLYM
Content-Type: application/x-ruby;
name="fb_3.rb"
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment;
filename="fb_3.rb"

#!/usr/bin/env ruby
# Ruby Quiz 126: FizzBuzz
# fb_3.rb

Fizz = 3
Buzz = 5
FizzBuzz = Fizz * Buzz

class Fixnum
alias :eek:ld_to_s :to_s
def to_s; (self % FizzBuzz).zero? ? 'FizzBuzz' :
(self % Fizz).zero? ? 'Fizz' :
(self % Buzz).zero? ? 'Buzz' :
old_to_s
end
end

# Peter Seebach's suggestion.
(1..100).each { |x| p x }

--Boundary-00=_dZ3YGrWwbOouLYM--
--Boundary-00=_dZ3YGrWwbOouLYM--
 
M

Matthew Moss

Okay, one more solution that just came to mind:

1.upto(100) do |i|
f, b = (i % 3).zero?, (i % 5).zero?
puts "#{'Fizz' if f}#{'Buzz' if b}#{i unless (f or b)}"
end
 
R

Robert Dober

----- Original Message -----
From: "Robert Dober" <[email protected]>
To: "ruby-talk ML" <[email protected]>
Sent: Sunday, June 03, 2007 6:38 PM
Subject: Re: [QUIZ] FizzBuzz (#126)

Sergey it is your fault if I cannot sleep ;), is this more readable ?
relax, Robert, nobody hurt :)
module Enumerable
def change(to, &blk)
map{ |x| blk.call(x) ? to : x }
end
end # module Enumerable

puts (1..100).change:)FizzBuzz){ |x| x%15 == 0 }.change:)Fizz){ |x|
x%3 == 0 rescue false}.change:)Buzz){ |x| x%5 == 0 rescue false }
hard to make formal conclusions - there are no formal requirements,
nor context is well defined, I can share my own opinion and potential
concerns only:

- yes, indeed, this solution is more readable,
compared to your Array-nested-tricky-indexed original solution;
- clear functional decomposition simplifies understanding, maintenance;
- it is easily expandable thanks to chain processing; I feel good ;)
btw: I prefer different name for Enumerable method, ex: substitute_if;
agreed and alias to change_if then there will be a substitute/change_unless too.
Not so attractive in this solution:
- run-time/memory inefficient: each item is generates 4 times;
- memory inefficient: generates and stores in memory 4*original array
Good point a change_if! might have been better.
(ex: not well suited for 10**9 length array); Too bad ;)
- can not be adopted for stream processing (read - process - print);
good point, but is that not the price to pay for functional decomposition?
- 'rescue' is for exceptional processing, should be avoided in normal
control flow;
I gotta think about this, I tend to agree for
begin
rescue ...
end
the inline form seems too compact for that and I do not consider it
control flow but rather a logical operator like
expression or_if_that_does_not_work other
but you do have a point.

Thx for your thoughts AAMOF you make me think that the discussion of
your solution with the recruiters is very important too.

Cheers
Robert
 
M

Morton Goldberg

Good prediction. You were right.

Well, if I'm on a roll, perhaps you'll tolerate some further semi-=20
random remarks about this quiz.

I guess a lot of us want new jobs.

I really like Fred Phillips' solution. A fine example of pursuing the =20=

KISS principle right into the ground. I wish I'd thought of it.

I don't envy you your job of having to summarize all these submissions.

Are the above remarks facetious? Mostly but not entirely.

Regards, Morton=
 
C

CHubas

The three rules of Ruby Quiz:

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

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

Robert Dober

On Jun 3, 2007, at 11:22 PM, James Edward Gray II wrote:
I really like Fred Phillips' solution.
Honestly the idea is awesome, but he should have taken care to get the
syntax right. I think it is not a good solution in the exact context
but a good distribution for us to have fun.
A fine example of pursuing the
KISS principle right into the ground. I wish I'd thought of it.
The KISS principle was already embraced by nobody less than Albert
Einstein who said "As simple(*) as possible, but not simpler!"
the last part being quite irrelevant in our case.
BUT does the merciless application of KISS give you the warm fuzzy feeling?
I believe - idiotically and idealistically ( they often come in pairs
) - that this warm fuzzy feeling is necessary to be productive. So
emotionally I dislike KISS somehow but I have to admit that I learnt a
lot while being put on my place ;)
I don't envy you your job of having to summarize all these submissions.

Sure and even more so, as we are already discussing solutions, which
have never seen before, and might even be bad form when I think about
it -maybe with the exception of the one liners. But this Quiz is
special :)

Knowing James a little bit he will find a practical approach making
his life a little bit easier and still giving a good resume, if he is
doing it himself BTW.

Are the above remarks facetious? Mostly but not entirely.

Regards, Morton
(*) I daresay that "simple" is not well defined though :)

Cheers
Robert
 
D

Daniel Martin

James Edward Gray II said:
Good prediction. You were right.

And yet, no one has so far posted a solution involving callcc or
threads. (unless I missed it)

I may have to go back for another round of interviews at
CompuGlobalMegaTech...
 

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

Forum statistics

Threads
473,755
Messages
2,569,535
Members
45,007
Latest member
obedient dusk

Latest Threads

Top