Q5: マージ
重複のない昇順の 2 つの無限ジェネレーター a と b を受け取り、両方のジェネレーターのすべての要素を昇順で重複のないジェネレーターを返すジェネレーター関数 merge を記述します。
def merge(a, b):
"""
>>> def sequence(start, step):
... while True:
... yield start
... start += step
>>> a = sequence(2, 3) # 2, 5, 8, 11, 14, ...
>>> b = sequence(3, 2) # 3, 5, 7, 9, 11, 13, 15, ...
>>> result = merge(a, b) # 2, 3, 5, 7, 8, 9, 11, 13, 14, 15
>>> [next(result) for _ in range(10)]
[2, 3, 5, 7, 8, 9, 11, 13, 14, 15]
"""
prev = float('-inf') # 省去了多写一遍循环内内容的麻烦
while True:
next_a, next_b = next(a), next(b)
while next_a <= prev:
next_a = next(a)
while next_b <= prev:
next_b = next(b)
if next_a != next_b:
if next_a < next_b:
yield next_a
yield next_b
else:
yield next_b
yield next_a
else:
yield next_a
prev = max(next_a, next_b)
Q6: 素数ジェネレーター
1 つの引数 n を取り、n 以下のすべての素数を降順で返す関数 primes_gen を作成します。n >= 1 と仮定します。ディスカッション 3 で実装した、以下に含まれる is_prime 関数を使用できます。
オプションの課題: 素数も昇順で出力するようにジェネレーターを書き直してください。
def is_prime(n):
"""Returns True if n is a prime number and False otherwise.
>>> is_prime(2)
True
>>> is_prime(16)
False
>>> is_prime(521)
True
"""
def helper(i):
if i > (n ** 0.5): # Could replace with i == n
return True
elif n % i == 0:
return False
return helper(i + 1)
return helper(2)
def primes_gen(n):
"""Generates primes in decreasing order.
>>> pg = primes_gen(7)
>>> list(pg)
[7, 5, 3, 2]
"""
if n < 2:
return
if is_prime(n):
yield n
yield from primes_gen(n - 1)
Q7: (オプション) ミステリーリバース環境図
グローバル フレーム内の変数が以下の値にバインドされるように、以下の行に入力します。イメージには完全な環境図は含まれていないことに注意してください。回答では、括弧、コロン、p および q のみを使用できます。
ヒント: 行き詰まった場合は、PythonTutor でさまざまな組み合わせを自由に試してみてください。
def mystery(p, q):
p[1].extend(q)
q.append(p[1:])
p = [2, 3]
q = [4, [p]]
mystery(q, p)
この問題はCS61Aの定番問題で、変数名の型を入れ替えて考える難しさを増しており、読みすぎると慣れてしまいます。
pythontutorでの結果は次のとおりです。