Sieve of Eratosthenes: Difference between revisions

→‎Infinite generator with a faster algorithm: change "bps.next()" to "next(bps)" for Python 2/3 compatibility; cleaned up code for speed...
(→‎Infinite generator with a faster algorithm: change "bps.next()" to "next(bps)" for Python 2/3 compatibility; cleaned up code for speed...)
Line 3,683:
===Infinite generator with a faster algorithm===
 
The adding of each discovered prime's incremental step info to the mapping should be '''''postponed''''' until the prime's ''square'' is seen amongst the candidate numbers, as it is useless before that point. This drastically reduces the space complexity from <code>O(n)</code> to <code>O(sqrt(n/log(n)))</code>, in ''<code>n</code>'' primes produced, and also lowers the run time complexity quite low ([http://ideone.com/t0vVqVXep9F this test entry] shows about <code>O(n^1.08)</code> [http://en.wikipedia.org/wiki/Analysis_of_algorithms#Empirical_orders_of_growth empirical order of growth] which is very close to the theoretical value of <code>O(n log(n) log(log(n)))</code>, in ''<code>n</code>'' primes produced):
<lang python>def primes():
yield 2 ; yield 3 ; yield 5 ; yield 7 ;
psbps = (p for p in primes()) # additional primes supply
p = ps.next(bps) and ps.next(bps) # discard 2, then get 3
q = p *p p # 9 - square of next prime to be put
sieve = {} # into sieve dict
n = 9 # the initial candidate number
while True:
if n not in sieve: # is not a multiple of previously recorded primes
if n < q: # n is prime
yield n # n is prime
else:
add(sieve,p2 q= p + 2*p, 2*p) # n == p * p: for prime p, underadd p * p + 2 * p,
psieve[q + p2] = ps.next()p2 # # add with 2 * p as incremental step
p = next(bps); q = p * p # advance base prime and next prime to be put
else:
s = sieve.pop(n); nxt = n + s # n is composite, advance
add(while nxt in sieve,: nnxt += s, s) # ensure each entry is unique
sieve[next] = step sieve[nxt] = s # next non-marked multiple of athis prime
n += 2 # work on odds only
def add(sieve,next,step):
while next in sieve: # ensure each entry is unique
next += step
sieve[next] = step # next non-marked multiple of a prime
 
import itertools
def primes_up_to(limit):
474

edits