Skip to content

Instantly share code, notes, and snippets.

@rctay
Forked from ejamesc/gist:1373187
Created November 17, 2011 18:26
Show Gist options
  • Save rctay/1373999 to your computer and use it in GitHub Desktop.
Save rctay/1373999 to your computer and use it in GitHub Desktop.
[fork] Sieve
"""Translated from Haskell:
let sieve(p:xs) = p : sieve (filter (\ x -> x `mod` p /= 0) xs) in sieve [2..]
"""
from itertools import ifilter
def ints(k):
while True:
yield k
k+=1
def sieve(g):
p = g.next()
yield p
g = sieve(ifilter(lambda x: x % p != 0, g))
while True:
yield next(g)
primes = sieve(ints(2))
# busts stack if +1
for i in xrange(996):
print next(primes)
"""Translated from Haskell:
let sieve(p:xs) = p : sieve (filter (\ x -> x `mod` p /= 0) xs) in sieve [2..]
"""
from itertools import ifilter
def ints(k):
while True:
yield k
k+=1
# needed due to scoping issues
def make_filter_pred(p):
return lambda x: x % p != 0
def sieve(g):
while True:
p = g.next()
yield p
g = ifilter(make_filter_pred(p), g)
primes = sieve(ints(2))
for i in xrange(10000):
print next(primes)
"""Translated from Haskell:
let sieve(p:xs) = p : sieve (filter (\ x -> x `mod` p /= 0) xs) in sieve [2..]
"""
from itertools import ifilter, chain
def ints(k):
while True:
yield k
k+=1
class sieve(object):
def __init__(self, g):
self.g = g
def __iter__(self):
p = self.g.next()
return chain([p], sieve(ifilter(lambda x: x % p != 0, self.g)))
primes = iter(sieve(ints(2)))
for i in xrange(10000):
print next(primes)
@ejamesc
Copy link

ejamesc commented Nov 17, 2011

  1. You're still awake.

  2. This is awesome shit. ;-)

@ejamesc
Copy link

ejamesc commented Nov 18, 2011

Also like how you managed to remove tail and head.

@rctay
Copy link
Author

rctay commented Nov 18, 2011

Yup, there's no need for head() and tail(), because we already have next(g) or g.next() for the former, and after running the former we've "advanced" the generator so that's tail().

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment