Skip to content

Commit 4c89d73

Browse files
authored
Merge pull request prateekiiest#62 from CaptainDaVinci/master
Segemented Sieve for Prime number generation.
2 parents c4909c2 + a490641 commit 4c89d73

File tree

1 file changed

+82
-15
lines changed

1 file changed

+82
-15
lines changed

Prime/code.py

Lines changed: 82 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,54 @@
1-
def SieveOfEratosthenes(range_to):
1+
from math import sqrt, ceil
22

3-
# creating a boolean array first
3+
4+
def segmented_sieve(range_from, range_to):
5+
"""
6+
Segmented sieve helps in providing a efficient way in terms of
7+
memory to find the prime numbers in a given range.
8+
9+
Space complexity: O(l)
10+
Time complexity: O(l * log(logl))
11+
12+
l = range_to - range_from
13+
"""
14+
15+
# if the range starts from 1, incerement it.
16+
if range_from == 1:
17+
range_from += 1
18+
19+
# initialize a boolean list of size l, with True.
20+
primes_range = [True for _ in range(range_to - range_from + 1)]
21+
22+
# generate primes upto sqrt(range_to) using Sieve of Eratosthenes.
23+
primes = sieve_eratosthenes(ceil(sqrt(range_to)))
24+
25+
# for every prime, all its multiples will not be prime
26+
for prime in primes:
27+
prime_multiple = max(range_from // prime, 2) * prime
28+
29+
# cross off all the multiple of the prime number.
30+
for i in range(prime_multiple, range_to + 1, prime):
31+
if i >= range_from:
32+
primes_range[i - range_from] = False
33+
34+
# return a list of prime numbers from range_from to range_to
35+
return [range_from + i for i, prime in enumerate(primes_range) if prime]
36+
37+
38+
def sieve_eratosthenes(range_to):
39+
"""
40+
A Very efficient way to generate all prime numbers upto a number.
41+
42+
Space complexity: O(n)
43+
Time complexity: O(n * log(logn))
44+
45+
n = the number upto which prime numbers are to be generated.
46+
"""
47+
48+
# creating a boolean list first
449
prime = [True for i in range(range_to + 1)]
550
p = 2
6-
while (p * p <= range_to):
51+
while (p * p <= range_to):
752

853
# If prime[p] is not changed, then it is a prime
954
if (prime[p] == True):
@@ -14,27 +59,49 @@ def SieveOfEratosthenes(range_to):
1459

1560
p += 1
1661

17-
print([p for p in range(2, range_to) if prime[p]])
62+
# return the list of primes
63+
return [p for p in range(2, range_to + 1) if prime[p]]
1864

1965

2066
def is_prime(num):
21-
for i in range(2, int(num / 2) + 1):
22-
if num % i == 0:
23-
return False
24-
return True
67+
"""
68+
Returns true is the number is prime.
69+
70+
To check if a number is prime, we need to check
71+
all its divisors upto only sqrt(number).
72+
73+
Reference: https://stackoverflow.com/a/5811176/7213370
74+
"""
75+
76+
# corner case. 1 is not a prime
77+
if num == 1:
78+
return False
79+
80+
# check if for a divisor upto sqrt(number)
81+
i = 2
82+
while i * i <= num:
83+
if num % i == 0:
84+
return False
85+
i += 1
86+
87+
return True
2588

2689

2790
def prime(range_from, range_to):
28-
allList = [num for num in range(range_from, range_to + 1) if is_prime(num)]
91+
"""
92+
Brute Force. O(l * sqrt(num)) [l = range_to - range_from]
93+
94+
Returns list of primes in the given range, by checking
95+
if the number is a prime or not.
96+
"""
97+
return [num for num in range(range_from, range_to + 1) if is_prime(num)]
98+
2999

30-
print("Prime List Between", range_from, "and", range_to, "is")
31-
print(allList)
32-
33-
34100
if __name__ == "__main__":
35101
print("Enter the range of number")
36102
range_from = int(input("From: "))
37103
range_to = int(input("To: "))
38104

39-
prime(range_from, range_to)
40-
SieveOfEratosthenes(range_to)
105+
print("Brute force:", prime(range_from, range_to), end="\n\n")
106+
print("Sieve of Eratosthenes:", sieve_eratosthenes(range_to), end="\n\n")
107+
print("Segmented Sieve:", segmented_sieve(range_from, range_to))

0 commit comments

Comments
 (0)