Quantcast
Channel: Sieve of Eratosthenes - Finding Primes Python - Stack Overflow
Viewing all articles
Browse latest Browse all 28

Answer by Andy Richter for Sieve of Eratosthenes - Finding Primes Python

$
0
0

Bitarray and 6k±1 for size and speed

1 billion in 5 seconds 2^24 in 3 milliseconds

I used bitarray for a smaller footprint. bitarray also allows statements like:

 p[4::2] = False  # Clear multiples of 2

The sieve code will do 1 billion sized sieve in about 5 seconds on my old i7

$ python prime_count_test.py Creating new sieve of 100,000,000 primes. Make sieve for 100,000,000 took 0:00:00.306957 Count primes to: >1000000000Creating new sieve of 1,000,000,000 primes. Make sieve for 1,000,000,000 took 0:00:04.734377 From 1 to 1,000,000,000 there are 50,847,534  primes Search took 0:00:04.856540 Primes from 1,000,000 to 1,000,200 are 1000003, 1000033, 1000037, 1000039, 1000081, 1000099, 1000117, 1000121, 1000133, 1000151, 1000159, 1000171, 1000183, 1000187, 1000193, 1000199Enter a number < 1,000,000,000  to test for prime> 1001710,017  is not prime

Here is my sieve:

from datetime import timedeltaimport timefrom bitarray import bitarraydef get_primes(a_prime, start=0, end=100):"""Return list of prime numbers in the range [start, end] using a_prime bitarray."""    return [i for i in range(start, end + 1) if a_prime[i]]def make_sieve(size):"""Create a sieve of Eratosthenes up to the given size."""    sieve_time = time.time()    print(f"Creating new sieve of {size:,} primes.")    limit = int(1 + size**0.5) + 2    p = bitarray(size)  # One bit per value    p.setall(True)    p[0] = p[1] = False    p[4::2] = False  # Clear multiples of 2    p[9::3] = False  # Clear multiples of 3    for i in range(5, limit, 6):  # Process only numbers of the form 6k-1 and 6k+1        h = i + 2  # 6k+1        if p[i]:  # If 6k-1 is prime            p[3 * i::2 * i] = False  # Clear multiples of 6k-1        if p[h]:  # If 6k+1 is prime            p[3 * h::2 * h] = False  # Clear multiples of 6k+1    print(f"Make sieve for {len(p):,} took {str(timedelta(seconds=time.time() - sieve_time))}")    return psieve_size = 10**8p = make_sieve(sieve_size)# Input for counting primes up to nn = int(input("Count primes to: >"))start_time = time.time()if n <= sieve_size:    prime_count = p[1:n + 1].count()else:    p = make_sieve(n)    prime_count = p[1:n + 1].count()    sieve_size = len(p)print(f"From 1 to {n:,} there are {prime_count:,} primes")print(f"Search took {str(timedelta(seconds=time.time() - start_time))}")# Get 200 primes from the sieve starting at 1,000,000print(f"\nPrimes from 1,000,000 to 1,000,200 are:")print(*get_primes(p, 10**6, 10**6 + 200), sep=', ')# Test if a specific number is primetest_p = int(input(f"\nEnter a number < {sieve_size:,} to test for prime> "))print(f"{test_p:,} {'is prime' if p[test_p] else 'is not prime'}")

To just return primes:

from datetime import timedeltaimport timefrom bitarray import bitarraydef get_primes(a_prime, start=0, end=100):"""Return list of prime numbers in the range [start, end] using a_prime bitarray."""    return [i for i in range(start, end + 1) if a_prime[i]]def make_sieve(size):"""Create a sieve of Eratosthenes up to the given size."""    sieve_time = time.time()    print(f"Creating new sieve of {size:,} primes.")    limit = int(1 + size**0.5) + 2    p = bitarray(size)  # One bit per value    p.setall(True)    p[0] = p[1] = False    p[4::2] = False  # Clear multiples of 2    p[9::3] = False  # Clear multiples of 3    for i in range(5, limit, 6):  # Process only numbers of the form 6k-1 and 6k+1        h = i + 2  # 6k+1        if p[i]:  # If 6k-1 is prime            p[i * i::2 * i] = False  # Clear multiples of 6k-1        if p[h]:  # If 6k+1 is prime            p[h * h::2 * h] = False  # Clear multiples of 6k+1    print(f"Make sieve for {len(p):,} took {str(timedelta(seconds=time.time() - sieve_time))}")    return [i for i in range(len(p)) if p[i]]start_time = time.time()n = 2**24p = make_sieve(n)print(f"From 1 to {n:,} there are {len(p):,} primes")print(p[0:200])

Output Takes about 3 milliseconds for 2**24 search:

$ python prime_count_test.py Creating new sieve of 16,777,216 primes.Make sieve for 16,777,216 took 0:00:00.034416From 1 to 16,777,216 there are 1,077,871 primes[2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211, 223, 227, 229, 233, 239, 241, 251, 257, 263, 269, 271, 277, 281, 283, 293, 307, 311, 313, 317, 331, 337, 347, 349, 353, 359, 367, 373, 379, 383, 389, 397, 401, 409, 419, 421, 431, 433, 439, 443, 449, 457, 461, 463, 467, 479, 487, 491, 499, 503, 509, 521, 523, 541, 547, 557, 563, 569, 571, 577, 587, 593, 599, 601, 607, 613, 617, 619, 631, 641, 643, 647, 653, 659, 661, 673, 677, 683, 691, 701, 709, 719, 727, 733, 739, 743, 751, 757, 761, 769, 773, 787, 797, 809, 811, 821, 823, 827, 829, 839, 853, 857, 859, 863, 877, 881, 883, 887, 907, 911, 919, 929, 937, 941, 947, 953, 967, 971, 977, 983, 991, 997, 1009, 1013, 1019, 1021, 1031, 1033, 1039, 1049, 1051, 1061, 1063, 1069, 1087, 1091, 1093, 1097, 1103, 1109, 1117, 1123, 1129, 1151, 1153, 1163, 1171, 1181, 1187, 1193, 1201, 1213, 1217, 1223]

Viewing all articles
Browse latest Browse all 28

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>