# Extended Fizz Buzz program
puts '★1行版'
puts [*1..100].map{|n| n % 15 == 0 ? 'FizzBuzz' : n % 5 ==0 ? 'Buzz' : n % 3 == 0 ? 'Fizz' : n}.join(' ')
puts '★複数処理の内部状態を合成した版'
puts [*1..100].map{|n|
["FizzBuzz", n, n, "Fizz", n, "Buzz", "Fizz", n, n, "Fizz", "Buzz", n, "Fizz", n, n, "FizzBuzz"][n % 15]
}.join(' ')
puts '★拡張性考慮版'
puts [*1..100].map{|n| # 数列の初期値と上限値を、両方同時に定義しているので、不十分
to_print = ''
to_print += 'Fizz' if n % 3 == 0 #判別条件の個数は、追加容易になったが
to_print += 'Buzz' if n % 5 == 0 #複雑な判別条件には、拡張性が無い
to_print.empty? ? n : to_print
}.join(' ') # 出力先がstring型を1個に固定化していて、拡張性不十分
#https://i...content-available-to-author-only...h.com/2007/01/24/using-fizzbuzz-to-find-developers-who-grok-coding/
puts '★ファイル分離&拡張版'
# # # # Producer1.rb
生産者 = Enumerator.new {|提出先|
(1..100).each{|生産物| 提出先.yield 生産物}
[1_000, 50_001, 100_000, 1_000_000].each{|先頭|
(1..19).each{|生産物| 提出先.yield (先頭 + 生産物)}
}
生産物 = 2_000_000
loop do # 上限値を決めないで、無限ループ
提出先.yield 生産物 += 1
end
}
# # # # Consumer1.rb
require 'fiber'
消費者達 = []
消費者達 << Fiber.new do |first|
puts '消費者Fizzが御仕事を始めます'
加工値 = nil
100.times do # 0から99までは、3の倍数の時Fizz
入力値 = Fiber.yield(加工値)
加工値 = (入力値 % 3 == 0) ? 'Fizz' : nil
end
loop do # 100以上で、10進表示に'3'が含まれれば、'Fizz'
入力値 = Fiber.yield(加工値)
加工値 = (入力値.to_s.include?('3') ? 'Fizz' : nil)
end
end
# # # # Consumer2.rb
消費者達 << Fiber.new do |first|
puts '消費者Buzzが御仕事を始めます'
加工値 = nil
50.times do # 1から53までは、5の倍数の時、Buzz
入力値 = Fiber.yield(加工値)
加工値 = (入力値 % 5 == 0) ? 'Buzz' : nil
end
loop do # 50以上の場合、奇数回目と偶数回目が異なる判別条件
入力値 = Fiber.yield(加工値) # 10進数表示に'5'が1個以上含まれれば、Buzz
加工値 = (入力値.to_s.count('5') > 0 ? 'Buzz' : nil)
入力値 = Fiber.yield(加工値) # 10進数表示に'5'が2個以上含まれれば、BuzzBuzz
加工値 = (入力値.to_s.count('5') > 1 ? 'BuzzBuzz' : nil)
end
end
# # # # Consumer3.rb
require 'prime'
消費者達 << Fiber.new do |first|
puts '消費者Quxが御仕事を始めます'
入力値 = first
加工値 = nil
5.times do
Fiber.yield(加工値)
end
loop do # 7以上の素数について
入力値 = Fiber.yield(加工値)
加工値 = (Prime.prime?(入力値) ? 'Qux' : nil)
end
end
# # # # integrate1.rb
統合消費者 = Enumerator.new do |統合先|
生産者.each do |生産物| # 消費者達の数にも判別条件にも独立
中間生産物 = 消費者達.map {|消費者| 消費者.resume(生産物)}
# 出力先の仕様変更の影響範囲を局所化
統合先 << (中間生産物.any? ? 中間生産物.compact.join(' ') : 生産物)
end
end
# 終了条件を”生産者”から分離している
統合消費者.take(161).each {|総合値| print 総合値; print ' '}