8
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Ruby1.9の勉強に使った FizzBuzz サンプル

Posted at

Golf

fizzbuzz_golf.rb
1.upto(100){|i|puts"#{[:Fizz][i%3]}#{[:Buzz][i%5]}"[/.+/]||i}

->、to_proc

fizzbuzz_proc.rb
def fizzbuzz
  -> n { n % 15 == 0 ? :FizzBuzz : n % 5 == 0 ? :Buzz : n % 3 == 0 ? :Fizz : n }
end
puts (1..100).map(&fizzbuzz)

オープンクラス、エイリアス、===

fizzbuzz_open.rb
class Fixnum
  IS_FIZZBUZZ = -> m, n { n % m == 0 }.curry
  alias _to_s to_s
  def to_s
    case self
    when IS_FIZZBUZZ[15]
      "FizzBuzz"
    when IS_FIZZBUZZ[5]
      "Buzz"
    when IS_FIZZBUZZ[3]
      "Fizz"
    else
      _to_s
    end
  end
end
puts [*1..100]  

例外、===

fizzbuzz_rescue.rb
def fizzbuzz(limit)
  e ||= 0
  ( e += 1 ) > limit ? return : raise
rescue lambda { |_| e % 15 == 0 }
  puts "FizzBuzz" ; retry
rescue lambda { |_| e % 5  == 0 }
  puts "Buzz"     ; retry
rescue lambda { |_| e % 3  == 0 }
  puts "Fizz"     ; retry
rescue lambda { |_| e }
  puts e          ; retry
end
fizzbuzz(100)

Enumerator、メソッドチェイン

fizzbuzz_chain.rb
puts 1.upto(100).with_object(nil)
                .map { |n, o| ( o ||= [] ) << :Fizz if n % 3 == 0; [n, o] }
                .map { |n, o| ( o ||= [] ) << :Buzz if n % 5 == 0; [n, o] }
                .map { |n, o| ( o || [n] ) * "" }

Converter、Filter、to_proc

fizzbuzz_converter.rb
class Converter
  
  def initialize
    @specs = []
  end
  
  def specs( value , &cond )
    @specs << lambda { |e| cond[e] ? value : nil }
  end
  
  def to_proc
    lambda { |e| 
      conved = @specs.map{ |spec| spec[e] }.join
      conved.empty? ? e : conved
    }
  end

end

if __FILE__ == $0

  arg   = ARGV[0] || 100
  limit = arg.to_i
  
  fizzbuzz  = Converter.new

  fizzbuzz.specs( "Fizz" ) { |n| n % 3 == 0 }
  fizzbuzz.specs( "Buzz" ) { |n| n % 5 == 0 }

  puts 1.upto(limit).map(&fizzbuzz)

end

クラス化

fizzbuzz_class.rb
class FizzBuzz
  
  def initialize( from = 1, to = 30 )
    @from, @to = [ from, to ].minmax
    block_given? ? yield( self ) : self
  end
  
  def spec( out, &cond )
    ( @specs ||= [] ) << lambda { |e| cond[ e ] ? out : nil }
  end
    
  def edit( &editor )
    @editor  = editor
  end
  
  def editor
    @editor || lambda { |e| e }
  end

  def format( &formatter )
    @formatter = formatter
  end
  
  def output( &formatter )
    @formatter = formatter if formatter
    result = @from.upto( @to ).map( &self )
    @formatter ?  result.map { |e| @formatter[ e ] } : result
  end

  def to_proc
    lambda { |i| 
      outs = @specs.map { |spec| spec[ i ] }
      editor[ i, outs ]
    }
  end  

end

実行方法

ruby fizzbuzz_main.rb

fizzbuzz_main.rb
require "./fizzbuzz"

# Pattern 1 : (1..30)
FizzBuzz.new do |fizzbuzz|

  fizzbuzz.spec( :Fizz ) { |e| e % 3 == 0 }
  fizzbuzz.spec( :Buzz ) { |e| e % 5 == 0 }

  fizzbuzz.edit { |i, outs| 
    out = outs.join
    out.empty? ? i : out
  }
  
end.output do |e|
  puts e
end

# Pattern 2 : (31..69)
fizzbuzz = FizzBuzz.new(31, 69)
fizzbuzz.edit { |i, outs| 
  out = outs.join
  out.empty? ? i : out
}
fizzbuzz.spec( :B ) { |e| e % 5 == 0 }
fizzbuzz.spec( :F ) { |e| e % 3 == 0 }
result = fizzbuzz.output
puts result * " "

# Pattern 3 : (70..105)
FizzBuzz.new(70, 105) do |fizzbuzz|

  fizzbuzz.spec( :Pizz ) { |e| e % 3 == 0 }
  fizzbuzz.spec( :Quzz ) { |e| e % 5 == 0 }
  fizzbuzz.spec( :Razz ) { |e| e % 7 == 0 }

  fizzbuzz.edit { |i, outs| 
    out = outs.join
    out.empty? ? i : out
  }
  
  fizzbuzz.format { |e| puts e }
  
end.output
8
7
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?