LoginSignup
7
5

More than 5 years have passed since last update.

怠惰な FizzBuzz を作ってみた

Last updated at Posted at 2017-11-16

怠惰な 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 版も実装しました。

:point_right: 怠惰な FizzBuzz を作ってみた (Python 版)

7
5
3

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
7
5