2

Hey I was given the fizzbuzz task recently and I had answered with the usual,

if ((i%3==0) || (i.to_s.include?('3'))) && ((i%7==0) || (i.to_s.include?('7')))
p 'Fizzbuzz'
elsif (i%3==0) || (i.to_s.include?('3'))
p 'Fizz'
elsif (i%7==0) || (i.to_s.include?('7'))
p 'Buzz'
else
p i
end

and when asked to shorten it I tried using ternary operators:

p (i%3<1 || i.to_s.include?('3')) ? ((i%7<1 || i.to_s.include?('7')) ? "Fizzbuzz" : "Fizz") : ((i%7<1 || i.to_s.include?('7')) ? "Buzz" : i)

but when asked to solve it using the Enumerable methods(select,reject,collect etc) I was well stumped...Any body tried this before??

The select/collect methods were specificaly mentioned so I'm guessing that he had something like this in mind(excuse the crappy code) (1..100).select { |i| i % 3 == 0 }.collect { "fizz" } but i'm stuck when trying to do this for the 3 conditions and print out the result(ie iterate through the output array) :\

Conor
  • 41
  • 4
  • 2
    It is generally considered a bad practice to nest ternary operator expressions. – sawa May 28 '13 at 23:38
  • 1
    What are you doing with expressions like `i.to_s.include?('3')`? Do you want numbers like `31` to be classified together with multiples of 3? – sawa May 28 '13 at 23:41
  • The usual? Just creating a string for every number to compare it with another number converted to a string? Well, in my time ... – steenslag May 28 '13 at 23:46
  • Yes, the solution needs to return Fizz if the number contains or is a multiple of 3 etc.. – Conor May 29 '13 at 00:07
  • Are you sure he didn't mean that he wanted you to include the code for enumerating over the numbers rather than use Enumerable for deciding what to print? – Chuck May 29 '13 at 00:14
  • 1
    Off topic, but still fun to [look](http://codegolf.stackexchange.com/questions/88/obfuscated-fizzbuzz-golf) at. – squiguy May 29 '13 at 00:21

5 Answers5

2

Probably not much help now, but I've produced a gem (fizzbuzzard) that monkey patches Fixnum such that all multiples of three print as Fizz, all multiples of five etc etc. Interviewers will respect you for using your knowledge of existing libraries rather than pointlessly re-solving solved problems.

Get it from rubgems here and find the source here.

The part I'm proudest of? The test suite. Output reproduced here:

(0h8m|master) [fizzbuzzard] $ rspec
.

Finished in 0 seconds
1 example, FIZZBUZZ failures
Russell
  • 12,261
  • 4
  • 52
  • 75
1
def fizzbuzz(i)
  [nil,nil,"Fizz",nil, nil,nil,"Buzz"].each_with_index do |fizz_or_buzz, idx|
    print fizz_or_buzz if (i.to_i % (1+idx)).zero?
  end
end

If the interviewer doesn't laugh, then it's probably not going to be a good fit (for me anyways).

Note that print doesn't add a newline (vs p)

See http://rosettacode.org/wiki/FizzBuzz#Ruby for more common solutions.

Shawn Balestracci
  • 7,380
  • 1
  • 34
  • 52
1

This one's a little dense but fun. It abuses arrays and some functional methods slightly to avoid using any if statements.

rules = {
  3 => ["fizz"],
  7 => ["buzz"]
}

(1..100).map do |n|
  [rules.map do |key, value|
    value[n % key]
  end.compact.join, n.to_s].find do |word|
    !word.empty?
  end
end.join("\n")
Daniel X Moore
  • 14,637
  • 17
  • 80
  • 92
0

It is not clean to repeat the same conditionals.

p case [
  i.%(3).zero? || i.to_s.include?("3"),
  i.%(7).zero? || i.to_s.include?("7")
]
when [true, true] then "Fizzbuzz"
when [true, false] then "Fizz"
when [false, true] then "Buzz"
when [false, false] then i
end
sawa
  • 165,429
  • 45
  • 277
  • 381
0

This hands you back the results in an array of strings, you can do whatever you want with them at that point.

results = (1..100).to_a.collect do |i|
  f = ((i%3).zero? || i.to_s.include?('3'))
  b = ((i%7).zero? || i.to_s.include?('7'))
  "#{:fizz if f}#{:buzz if b}#{i unless f || b}"
end
p results
pjs
  • 18,696
  • 4
  • 27
  • 56