分岐の問題なんですが、単純な繰り返しでもある。
def fizzbuzz_gen():
F = "Fizz"
B = "Buzz"
FB = "Fizz Buzz"
i = 0
while True:
yield from (
i+1, i+2, F, i+4, B
, F, i+7, i+8, F, B
, i+11, F, i+13, i+14, FB
)
i += 15
fb = fizzbuzz_gen()
N = int(input())
for _ in range(N):
print(next(fb))
分岐なしでやってみました。無駄な演算をなるべく減らしてみます。
unbox = lambda *xs: xs[-1]
def count_gen(i):
while True:
yield i
i += 1
def fizzbuzz_gen():
F = "Fizz"
B = "Buzz"
FB = "Fizz Buzz"
c = count_gen(1)
while True:
yield from (
next(c), next(c), unbox(next(c), F)
, next(c), unbox(next(c), B), unbox(next(c), F)
, next(c), next(c), unbox(next(c), F)
, unbox(next(c), B), next(c), unbox(next(c), F)
, next(c), next(c), unbox(next(c), FB)
)
fb = fizzbuzz_gen()
N = int(input())
for _ in range(N):
print(next(fb))
あるいは:
def count_gen(i):
while True:
yield i
i += 1
def fizz_gen():
c = count_gen(1)
while True:
for _ in range(1, 3):
yield next(c)
next(c)
yield "Fizz"
def fizzbuzz_gen():
f = fizz_gen()
while True:
for _ in range(1, 3):
for _ in range(1, 5):
yield next(f)
next(f)
yield "Buzz"
for _ in range(1, 5):
yield next(f)
next(f)
yield "Fizz Buzz"
fb = fizzbuzz_gen()
N = int(input())
for _ in range(N):
print(next(fb))
現物を並べただけだとおばかっぽく見えるので。
普段はFizzのジェネレーターの値を採用して、Buzz、FizzBuzzのときだけ "Buzz"、"Fizz Buzz" を返す、って感じです。