find all multiplicands and multipliers for a number
Paul Rubin
no.email at nospam.invalid
Tue Apr 14 22:37:19 EDT 2015
Steven D'Aprano <steve+comp.lang.python at pearwood.info> writes:
> primes = sieve [2..]
> sieve (p : xs) = p : sieve [x | x <- xs, x `mod` p > 0]
> In her paper http://www.cs.hmc.edu/~oneill/papers/Sieve-JFP.pdf, Melissa
> O'Neill calls this the "Sleight on Eratosthenes".
Oh cool, I wrote very similar Haskell code and converted it to Python.
I probably saw it before though, so it looks like a case of
not-exactly-independent re-invention.
> def turner():
> nums = itertools.count(2)
> while True:
> prime = next(nums)
> yield prime
> nums = filter(lambda v, p=prime: (v % p) != 0, nums)
This is nice, though it will still hit the nesting limit about equally
soon, because of the nested filters. I like the faster versions in the
O'Neill paper.
> On my computer, your recursive version is about 35% slower than the
> iterative version over the first 499 primes.
Interesting. I wonder why it's slower.
A Hamming (or "5-smooth") number is a number with no prime factors
larger than 5. So 20 (= 2*2*5) is a Hamming number but 21 (= 3*7) is
not. The first few of them are:
[1, 2, 3, 4, 5, 6, 8, 9, 10, 12, 15, 16, 18, 20, 24]
Here's an ugly computation of the millionth Hamming number, converted
from Haskell code that you've probably seen. I'd be interested in
seeing a cleaner implementation.
================================================================
import itertools, time
def merge(a0,b0):
def advance(m): m[0] = next(m[1])
a = [next(a0), a0]
b = [next(b0), b0]
while True:
if a[0] == b[0]:
yield a[0]
advance(a)
advance(b)
elif a[0] < b[0]:
yield a[0]
advance(a)
else:
yield b[0]
advance(b)
def hamming(n):
hh = [1]
def hmap(k):
for i in itertools.count():
yield k * hh[i]
m = merge(hmap(2),merge(hmap(3), hmap(5)))
for i in xrange(n):
hh.append(next(m))
return hh[-1]
# this takes about 2.4 seconds on my i5 laptop with python 2.7,
# about 2.8 sec with python 3.3.2
t0=time.time()
print (hamming(10**6-1))
print (time.time()-t0)
================================================================
More information about the Python-list
mailing list