RosettaCodeData/Task/Hamming-numbers/Python/hamming-numbers-6.py

39 lines
758 B
Python

from itertools import islice, chain, tee
def merge(r, s):
# This is faster than heapq.merge.
rr = r.next()
ss = s.next()
while True:
if rr < ss:
yield rr
rr = r.next()
else:
yield ss
ss = s.next()
def p(n):
def gen():
x = n
while True:
yield x
x *= n
return gen()
def pp(n, s):
def gen():
for x in (merge(s, chain([n], (n * y for y in fb)))):
yield x
r, fb = tee(gen())
return r
def hamming(a, b = None):
if not b:
b = a + 1
seq = (chain([1], pp(5, pp(3, p(2)))))
return list(islice(seq, a - 1, b - 1))
print hamming(1, 21)
print hamming(1691)[0]
print hamming(1000000)[0]