TheAlgorithms-Python
79 строк · 1.7 Кб
1"""Segmented Sieve."""
2
3import math
4
5
6def sieve(n: int) -> list[int]:
7"""
8Segmented Sieve.
9
10Examples:
11>>> sieve(8)
12[2, 3, 5, 7]
13
14>>> sieve(27)
15[2, 3, 5, 7, 11, 13, 17, 19, 23]
16
17>>> sieve(0)
18Traceback (most recent call last):
19...
20ValueError: Number 0 must instead be a positive integer
21
22>>> sieve(-1)
23Traceback (most recent call last):
24...
25ValueError: Number -1 must instead be a positive integer
26
27>>> sieve(22.2)
28Traceback (most recent call last):
29...
30ValueError: Number 22.2 must instead be a positive integer
31"""
32
33if n <= 0 or isinstance(n, float):
34msg = f"Number {n} must instead be a positive integer"
35raise ValueError(msg)
36
37in_prime = []
38start = 2
39end = int(math.sqrt(n)) # Size of every segment
40temp = [True] * (end + 1)
41prime = []
42
43while start <= end:
44if temp[start] is True:
45in_prime.append(start)
46for i in range(start * start, end + 1, start):
47temp[i] = False
48start += 1
49prime += in_prime
50
51low = end + 1
52high = min(2 * end, n)
53
54while low <= n:
55temp = [True] * (high - low + 1)
56for each in in_prime:
57t = math.floor(low / each) * each
58if t < low:
59t += each
60
61for j in range(t, high + 1, each):
62temp[j - low] = False
63
64for j in range(len(temp)):
65if temp[j] is True:
66prime.append(j + low)
67
68low = high + 1
69high = min(high + end, n)
70
71return prime
72
73
74if __name__ == "__main__":
75import doctest
76
77doctest.testmod()
78
79print(f"{sieve(10**6) = }")
80