Created
March 15, 2014 05:58
-
-
Save djrodgerspryor/9562401 to your computer and use it in GitHub Desktop.
A module for lazily generating prime numbers with python generators and the Sieve of Eratosthenes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from itertools import takewhile, chain, count, islice | |
from collections import deque | |
knownPrimes = [2] # Numbers are tested by counting upwards from here. This also acts as a cache. | |
def storeAndReturn(p): | |
knownPrimes.append(p) | |
return p | |
def isNotDivisibleByKnownPrimes(n): | |
root_n = n**0.5 # Square root of n | |
return all((n % p) != 0 for p in takewhile(lambda p: p <= root_n, knownPrimes)) # Test for divisibility by known primes <= sqrt(n) | |
def primeFilter(sequence): return (storeAndReturn(i) for i in sequence if isNotDivisibleByKnownPrimes(i)) | |
def allPrimes(): return chain(knownPrimes, primeFilter(count(knownPrimes[-1] + 1))) | |
def primesUpTo(limit): return takewhile(lambda p: p < limit, allPrimes()) | |
def firstNPrimes(n): return islice(allPrimes(), None, n, None) | |
def nthPrime(n): return deque(firstNPrimes(n), maxlen=1).pop() # deque construction is apparently the | |
# fastest way to consume an iterator (partly because it's raw C) | |
if __name__ == '__main__': # Module Test | |
print "Primes below 20:" | |
print '\n'.join(map(str, primesUpTo(20))) | |
print "First 10 primes:" | |
print '\n'.join(map(str, firstNPrimes(10))) | |
print "10,000th prime:" | |
print nthPrime(10000) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment