from itertools import *
def wsieve(): # wheel-sieve, by Will Ness. ideone.com/trR9OI
yield 11 # cf. ideone.com/WFv4f
mults = {} # codereview.stackexchange.com/q/92365/9064
ps = wsieve()
p = next(ps) # 11
psq = p*p # 121
D = dict( zip( accumulate( [0, # where to start
2,4,2,4,6,2,6,4,2,4,6,6, 2,6,4,2,6,4,6,8,4,2,4,2,
4,8,6,4,6,2,4,6,2,6,6,4, 2,4,6,2,6,4,2,4,2,10,2,10] ),
count(0)))
for c in accumulate( chain( [13], cycle(
[ 4,2,4,6,2,6,4,2,4,6,6, 2,6,4,2,6,4,6,8,4,2,4,2,
4,8,6,4,6,2,4,6,2,6,6,4, 2,4,6,2,6,4,2,4,2,10,2,10,2] ))):
if c in mults:
wheel = mults.pop(c)
elif c < psq:
yield c ; continue
else: # (c==psq)
p2=p*2 ; p6=p*6 ; p10=p*10 # map (p*) (roll wh from p) =
p4=p*4 ; p8=p*8 # = roll (wh*p) from p*p
wheel = accumulate( chain( [p*p], islice( cycle(
[p2,p4,p2,p4,p6,p2,p6,p4,p2,p4,p6,p6,
p2,p6,p4,p2,p6,p4,p6,p8,p4,p2,p4,p2,
p4,p8,p6,p4,p6,p2,p4,p6,p2,p6,p6,p4,
p2,p4,p6,p2,p6,p4,p2,p4,p2,p10,p2,p10] ),
D[ (p-11) % 210 ], None )))
p = next(ps) ; psq = p*p ; next(wheel) # p*p
for m in wheel:
if not m in mults:
break
mults[m] = wheel
def primes():
yield from (2, 3, 5, 7)
yield from wsieve()
if True:
n = 1000000 # ! 1.5x speedup vs nw1BQn: 1M 5.1/3.4 2M 10.88/7.2
print(n)
print( list( islice( (p for p in primes() ), n-1, n+1)))
ZnJvbSBpdGVydG9vbHMgaW1wb3J0ICoKCmRlZiB3c2lldmUoKTogICAgICAgIyB3aGVlbC1zaWV2ZSwgYnkgV2lsbCBOZXNzLiAgIGlkZW9uZS5jb20vdHJSOU9JCiAgICB5aWVsZCAxMSAgICAgICAgIyBjZi4gaWRlb25lLmNvbS9XRnY0ZgogICAgbXVsdHMgPSB7fSAgICAgICMgICAgIGNvZGVyZXZpZXcuc3RhY2tleGNoYW5nZS5jb20vcS85MjM2NS85MDY0CiAgICBwcyA9IHdzaWV2ZSgpICAgCiAgICBwID0gbmV4dChwcykgICAgICAgIyAxMQogICAgcHNxID0gcCpwICAgICAgICAgICMgMTIxCiAgICBEID0gZGljdCggemlwKCBhY2N1bXVsYXRlKCBbMCwgICAgICAgIyB3aGVyZSB0byBzdGFydAogICAgICAgICAgICAgICAgIDIsNCwyLDQsNiwyLDYsNCwyLDQsNiw2LCAyLDYsNCwyLDYsNCw2LDgsNCwyLDQsMiwKICAgICAgICAgICAgICAgICA0LDgsNiw0LDYsMiw0LDYsMiw2LDYsNCwgMiw0LDYsMiw2LDQsMiw0LDIsMTAsMiwxMF0gKSwKICAgICAgICAgICAgICAgICAgIGNvdW50KDApKSkKICAgIGZvciBjIGluIGFjY3VtdWxhdGUoIGNoYWluKCBbMTNdLCBjeWNsZSggCiAgICAgICAgICAgICAgICBbICA0LDIsNCw2LDIsNiw0LDIsNCw2LDYsIDIsNiw0LDIsNiw0LDYsOCw0LDIsNCwyLAogICAgICAgICAgICAgICAgIDQsOCw2LDQsNiwyLDQsNiwyLDYsNiw0LCAyLDQsNiwyLDYsNCwyLDQsMiwxMCwyLDEwLDJdICkpKToKICAgICAgICBpZiBjIGluIG11bHRzOgogICAgICAgICAgICB3aGVlbCA9IG11bHRzLnBvcChjKSAgCiAgICAgICAgZWxpZiBjIDwgcHNxOiAgICAgICAgICAgICAgCiAgICAgICAgICAgIHlpZWxkIGMgOyBjb250aW51ZSAgIAogICAgICAgIGVsc2U6ICAgICAgICAgICMgKGM9PXBzcSkgICAKICAgICAgICAgICAgcDI9cCoyICAgOyAgIHA2PXAqNiAgIDsgIHAxMD1wKjEwICMgbWFwIChwKikgKHJvbGwgd2ggZnJvbSBwKSA9CiAgICAgICAgICAgIHA0PXAqNCAgIDsgICBwOD1wKjggICAgICAgICAgICAgICAjICA9IHJvbGwgKHdoKnApIGZyb20gcCpwCiAgICAgICAgICAgIHdoZWVsID0gYWNjdW11bGF0ZSggY2hhaW4oIFtwKnBdLCBpc2xpY2UoIGN5Y2xlKCAKICAgICAgICAgICAgICAgICAgICAgICAgICBbcDIscDQscDIscDQscDYscDIscDYscDQscDIscDQscDYscDYsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIHAyLHA2LHA0LHAyLHA2LHA0LHA2LHA4LHA0LHAyLHA0LHAyLAogICAgICAgICAgICAgICAgICAgICAgICAgICBwNCxwOCxwNixwNCxwNixwMixwNCxwNixwMixwNixwNixwNCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgcDIscDQscDYscDIscDYscDQscDIscDQscDIscDEwLHAyLHAxMF0gKSwKICAgICAgICAgICAgICAgICAgICAgICAgICBEWyAocC0xMSkgJSAyMTAgXSwgTm9uZSApKSkKICAgICAgICAgICAgcCA9IG5leHQocHMpIDsgcHNxID0gcCpwIDsgbmV4dCh3aGVlbCkgICAjIHAqcAogICAgICAgIGZvciBtIGluIHdoZWVsOiAKICAgICAgICAgICAgaWYgbm90IG0gaW4gbXVsdHM6IAogICAgICAgICAgICAgICAgYnJlYWsKICAgICAgICBtdWx0c1ttXSA9IHdoZWVsCiAgICAgICAgCmRlZiBwcmltZXMoKTogCgl5aWVsZCBmcm9tICgyLCAzLCA1LCA3KQoJeWllbGQgZnJvbSB3c2lldmUoKSAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgCmlmIFRydWU6ICAgICAgICAgICAgICAgICAgIAogICAgbiA9IDEwMDAwMDAgICMgISAxLjV4IHNwZWVkdXAgdnMgbncxQlFuOiAxTSA1LjEvMy40ICAyTSAxMC44OC83LjIKICAgIHByaW50KG4pIAogICAgcHJpbnQoIGxpc3QoIGlzbGljZSggKHAgZm9yIHAgaW4gcHJpbWVzKCkgKSwgbi0xLCBuKzEpKSkgICA=