File: sieve.py

package info (click to toggle)
python-bitarray 3.7.2-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 1,320 kB
  • sloc: python: 11,753; ansic: 7,680; makefile: 73; sh: 6
file content (54 lines) | stat: -rw-r--r-- 1,571 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
"""
Demonstrates the implementation of "Sieve of Eratosthenes" algorithm for
finding all prime numbers up to any given limit.

It should be noted that bitarray version 3.7 added util.gen_primes().
The library function basically uses an optimized version of the same
algorithm.
"""
from math import isqrt

from bitarray import bitarray
from bitarray.util import ones, count_n, sum_indices


N = 100_000_000

# Each bit a[i] corresponds to whether or not i is a prime
a = ones(N)

# Zero and one are not prime
a[:2] = False

# Perform sieve
for i in range(2, isqrt(N) + 1):
    if a[i]:  # i is prime, so all multiples are not
        a[i*i::i] = False

stop = 50
print('primes up to %d are:' % stop)
print(list(a.search(1, 0, stop)))

# There are 5,761,455 primes up to 100 million
x = a.count()
print('there are {:,d} primes up to {:,d}'.format(x, N))
assert x == 5_761_455 or N != 100_000_000

# The number of twin primes up to 100 million is 440,312
# we need to add 1 as .count() only counts non-overlapping sub_bitarrays
# and (3, 5) as well as (5, 7) are both twin primes
x = a.count(bitarray('101')) + 1
print('number of twin primes up to {:,d} is {:,d}'.format(N, x))
assert x == 440_312 or N != 100_000_000

# The 1 millionth prime number is 15,485,863
m = 1_000_000
x = count_n(a, m) - 1
print('the {:,d}-th prime is {:,d}'.format(m, x))
assert x == 15_485_863

# The sum of all prime numbers below one million is 37,550,402,023.
m = 1_000_000
x = sum_indices(a[:m])
print('the sum of prime numbers below {:,d} is {:,d}'.format(m, x))
assert x == 37_550_402_023