Skip to content

Instantly share code, notes, and snippets.

@Kerrick
Created April 24, 2012 20:36
Show Gist options
  • Save Kerrick/2483510 to your computer and use it in GitHub Desktop.
Save Kerrick/2483510 to your computer and use it in GitHub Desktop.
Different solutions for Fizz Buzz in Ruby
def fizz_buzz_1(max)
arr = []
(1..max).each do |n|
if ((n % 3 == 0) && (n % 5 == 0))
arr << "FizzBuzz"
elsif (n % 3 == 0)
arr << "Fizz"
elsif (n % 5 == 0)
arr << "Buzz"
else
arr << n
end
end
return arr
end
def fizz_buzz_2(max)
arr = []
(1..max).each do |n|
if (n % 3 == 0)
if (n % 5 == 0)
arr << "FizzBuzz"
else
arr << "Fizz"
end
elsif (n % 5 == 0)
arr << "Buzz"
else
arr << n
end
end
return arr
end
def fizz_buzz_3(max)
arr = []
(1..max).each do |n|
text = ""
if (n % 3 == 0)
text << "Fizz"
end
if (n % 5 == 0)
text << "Buzz"
end
if !((n % 3 == 0) || (n % 5 == 0))
text = n
end
arr << text
end
return arr
end
@alessandro-martin
Copy link

(1..42).each do | n, fb |
fb = fb.to_s + "Fizz" if n%3==0
fb = fb.to_s + "Buzz" if n%5==0
puts fb || n
end

@philcallister
Copy link

A little too much fun with FizzBuzz...

module FunFizzBuzz

  class ModResult
    include Comparable
    attr_accessor :mod, :result_proc

    def initialize(mod, result_proc)
      self.mod = mod
      self.result_proc = result_proc
    end

    def <=> other
      self.mod <=> other.mod
    end

  end

  class Sequencer
    attr_accessor :max

    def initialize(max)
      self.max = max
    end

    def sequence(mod_procs)
      mps = mod_procs.sort.reverse # need to test biggest divisors first
      (1..self.max).each do |i|
        mp_found = mps.detect { |mp| i % mp.mod == 0 }
        puts mp_found ? mp_found.result_proc.call(i) : block_given? ? yield(i) : i 
      end
    end

  end

end

s = FunFizzBuzz::Sequencer.new(100)
mps = [FunFizzBuzz::ModResult.new(3, Proc.new { |i| "Fizz" }), FunFizzBuzz::ModResult.new(5, Proc.new { |i| "Buzz" }), FunFizzBuzz::ModResult.new(15, Proc.new { |i| "FizzBuzz" })]
s.sequence(mps)

mps = [FunFizzBuzz::ModResult.new(2, Proc.new { |i| "FizzNew #{i}" }), FunFizzBuzz::ModResult.new(3, Proc.new { |i| "BuzzNew #{i}" }), FunFizzBuzz::ModResult.new(6, Proc.new { |i| "FizzBuzzNew #{i}" })]
s.sequence(mps)

@ethagnawl
Copy link

+1 for @jordanpoulton's approach/solution.

@gvost
Copy link

gvost commented Oct 15, 2014

1.step(100,1) do |i|
    if (i % 5) == 0 && (i % 3) ==0
        puts 'FizzBuzz'
    elsif (i % 5) == 0
        puts 'Buzz'
    elsif (i % 3) == 0
        puts 'Fizz'
    else
        puts i
    end
end

@steobrien
Copy link

NAMED_FACTORS = {
  3 => 'Fizz',
  5 => 'Buzz'
}

def evenly_divides?(numerator, denominator)
  numerator % denominator == 0
end

def named_factors(number)
  NAMED_FACTORS.map do |factor, name|
    name if evenly_divides?(number, factor)
  end.compact
end

def transform(range)
  range.map do |number|
    names = named_factors(number)
    names.any? ? names.join : number
  end
end

transform(1..100)

@yoshikischmitz
Copy link

Poor man's pattern matching:

fizzbuzz =
  (1..100).map do |n|
    case [n % 3, n % 5].map(&:zero?)
    when [true, true]
      "FizzBuzz"
    when [true, false]
      "Fizz"
    when [false, true]
      "Buzz"
    else
      n
    end
  end
puts fizzbuzz

What I like about this approach is that you avoid the duplicate n % x == 0 conditions that are necessary in the if else version without having to resort to i % 15 which always seemed hacky to me, without going too crazy like many of the purely un-conditional fizzbuzzes out there.

@davekinkead
Copy link

How many times has this problem been solved already? Idiomatic Ruby embraces the DRY principle. Not just in your own code base, but the entire internet.

require 'curb'
require 'nokogiri'

class Dry

  # Why copy & paste answers from stack overflow when you can curl & eval them!
  # Expects a url#answer-id and a hash of adjustments to the answer code to gsub over
  def self.fuck_it_just_copy_something_from_stackoverflow(url, adjustments)
    # build the adjustment lambda
    edit = "lambda { |method_string| method_string"
    adjustments.each { |k,v| edit += ".gsub('#{k}', '#{v}')" }
    edit += "}"

    # then get some of that overflow goodness
    answer = url.split('#').last
    @doc ||= Nokogiri::HTML Curl.get(url).body_str
    @doc.css("#answer-#{answer} code").each do |code|
      # Oh yeah, it's lambda time! Eval the edit string, pass it the overflow code and eval the resulting lambda
      return eval eval(edit).call code.content
    end
  end
end

100.times do |number|
  url = 'http://stackoverflow.com/questions/24435547/ruby-fizzbuzz-not-working-as-expected#24435693'
  adjustments = {'puts' => 'return', 'def fizzbuzz(n)' => 'lambda do |n|'}
  p Dry.fuck_it_just_copy_something_from_stackoverflow(url, adjustments).call(number).last.to_s
end

@AntoineBecquet
Copy link

I really like this solution from reddit:

a=b=c=(1..100).each do |num|
  print num, ?\r,
    ("Fizz" unless (a = !a) .. (a = !a)),
    ("Buzz" unless (b = !b) ... !((c = !c) .. (c = !c))),
    ?\n
end

@willwright82
Copy link

fizz_buzz =
    (1..100).map do |i|
        case
        when i % 15 == 0 then "FizzBuzz"
        when i % 3 == 0 then "Fizz"
        when i % 5 == 0 then "Buzz"
        else i
        end
    end
puts fizz_buzz

@fjezdik123
Copy link

low=1
high=100
      (low..high).each {|x|
       puts x%15==0?'FizzBuzz':x%5==0?'Buzz':x%3==0?'Fizz':x
      }

@andrewstucki
Copy link

andrewstucki commented May 2, 2016

_=$$/$$;__=_-_;@_=_+_;$_=@_+_;$__=@_+$_;$-_=$__*$_;@__=''<<$-_*($__+$_)+@_;$___=''<<$-_*$__-$__<<$-_*($__+@_)<<@__<<@__;@___=''<<$-_*$__-$_*$_<<$-_*($__+$_)-$_<<@__<<@__;(___=->{$.+=_;$><<($.%$-_==__ ?$___+@___:$.%$_==__ ?$___:$.%$__==__ ?@___:$.)<<(''<<$__*@_);$.<($__*@_)**@_?___[]:_})[]

Thanks to http://threeifbywhiskey.github.io/2014/03/05/non-alphanumeric-ruby-for-fun-and-not-much-else/

@McTano
Copy link

McTano commented May 17, 2016

(1..100).each do |x|
  fizz = "Fizz" if (x % 3 == 0)
  buzz = "Buzz" if (x % 5 == 0)
  puts (fizz || buzz) ? fizz.to_s + buzz.to_s : x
end

@ragesoss
Copy link

ragesoss commented Jul 7, 2016

class Fixnum
  def to_s
    string = ''
    string += 'fizz' if self % 3 == 0
    string += 'buzz' if self % 5 == 0
    return string unless string.empty?
    inspect
  end
end

puts (1..100).to_a

@algex
Copy link

algex commented Oct 20, 2016

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

end

@g-mehra
Copy link

g-mehra commented Jan 16, 2017

#FizzBuzz

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

@besya
Copy link

besya commented Mar 9, 2017

buzzer = lambda do |i|
  map = {ff: i, tf: 'Fizz', ft: 'Buzz', tt: 'FizzBuzz'}
  map[((i%3==0).to_s[0] + (i%5==0).to_s[0]).to_sym]
end
puts (1..100).map(&buzzer)

@juhaniahola
Copy link

juhaniahola commented May 5, 2017

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

#66 chars :)

@dankohn
Copy link

dankohn commented Dec 31, 2017

This one requires presence from Rails (i.e., it works in rails console):

puts 1.upto(100).map { |n| "#{'Fizz' if n%3==0}#{'Buzz' if n%5==0}".presence || n }

@Aketzu
Copy link

Aketzu commented Feb 13, 2018

(1..100).map{|n|({3=>['Fizz'],5=>['Buzz']}.map{|x,y|y[n%x]}.join.gsub(/^$/,n.to_s))}

@kke
Copy link

kke commented May 3, 2018

@willwright82 's solution modified for less == 0:

(1..100).map do |m|
  case 0
  when m % 15 then 'FizzBuzz'
  when m % 3  then 'Fizz'
  when m % 5  then 'Buzz'
  else m
  end
end

@coryjanowski
Copy link

def fizzbuzz(int)
if int % 3 == 0 && int % 5 == 0
"FizzBuzz"
elsif int % 3 == 0
"Fizz"
elsif int % 5 == 0
"Buzz"
else int % 4 == 0
nil
end
end

@lux9
Copy link

lux9 commented Oct 5, 2020

70 characters

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

@khamusa
Copy link

khamusa commented Apr 29, 2021

When I thought we already had way too many solutions... !

module BeingMultiple
  refine Integer do
    def eitherFizzOrBuzz!
      return "FizzBuzz" if multiple?(3) && multiple?(5)
      return "Fizz" if multiple?(3)
      return "Buzz" if multiple?(5)
      self
    end
    
    private
    
    def multiple?(target)
      self % target == 0
    end
  end
end

using BeingMultiple

puts (1..n).map(&:eitherFizzOrBuzz!).join("\n")

@al3rez
Copy link

al3rez commented Sep 7, 2021

require "fizzbuzz"

RSpec.describe FizzBuzz do
  describe "#compute" do
    context "when number is dvisisble by 3" do
      it "returns fizz" do
        expect(FizzBuzz.compute(6)).to eq("fizz")
      end
    end

    context "when number is dvisisble by 5" do
      it "returns buzz" do
        expect(FizzBuzz.compute(10)).to eq("buzz")
      end
    end

    context "when number is dvisisble by both 3 and 5" do
      it "returns buzz" do
        expect(FizzBuzz.compute(15)).to eq("fizzbuzz")
      end
    end
  end
end


class FizzBuzz
  def self.compute(number)
    return "fizzbuzz" if (number % 15).zero?

    if (number % 3).zero? "fizz" else "buzz" end
  end
end

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment