怠惰な FizzBuzz
お風呂に入ろうとしていたら、突然思いついたのですかさず試してメモしました。
def genarate_lazy_list(number, yell)
loop.lazy.flat_map { [*Array.new(number - 1, nil), yell] }
end
numbers = 1.step.lazy
fizzes = genarate_lazy_list(3,'Fizz')
buzzes = genarate_lazy_list(5,'Buzz')
fizzbuzzes = genarate_lazy_list(15,'FizzBuzz')
# irb 用にバックスラッシュを付けている。ドットを行末に書くより行頭に書きたい派なので。
numbers \
.zip(fizzes, buzzes, fizzbuzzes) \
.map { |n, fizz, buzz, fizzbuzz| fizzbuzz || buzz || fizz || n } \
.take(30) \
.each(&method(:puts))
stdout
1
2
Fizz
4
Buzz
Fizz
7
8
Fizz
Buzz
11
Fizz
13
14
FizzBuzz
16
17
Fizz
19
Buzz
Fizz
22
23
Fizz
Buzz
26
Fizz
28
29
FizzBuzz
fizzbuzzes
が冗長だと思う場合は
require 'active_support'
require 'active_support/core_ext/object/blank'
numbers \
.zip(fizzes, buzzes) \
.map { |n, fizz, buzz| "#{fizz}#{buzz}".presence || n } \
.take(30) \
.each(&method(:puts))
宣言的な FizzBuzz
お風呂の中で思いついた。
# say(Fizz or Buzz or FizzBuzz).for_multiples_of(number) と書けるようにする。
def say(fizzbuzz)
def fizzbuzz.for_multiples_of(number)
loop.lazy.flat_map { [*Array.new(number - 1, nil), self] }
end
fizzbuzz
end
numbers = 1.step.lazy
fizzes = say('Fizz').for_multiples_of(3)
buzzes = say('Buzz').for_multiples_of(5)
fizzbuzzes = say('FizzBuzz').for_multiples_of(15)
numbers \
.zip(fizzes, buzzes, fizzbuzzes) \
.map { |n, fizz, buzz, fizzbuzz| fizzbuzz || buzz || fizz || n } \
.take(30) \
.each(&method(:puts))
おまけ
Python 版も実装しました。