Skip to content

Commit 3374ede

Browse files
AyhamJo7pre-commit-ci[bot]cclauss
authored
Add Sieve of Atkin algorithm for efficient prime generation (#12974)
* Add Sieve of Atkin algorithm for efficient prime generation Implement the Sieve of Atkin algorithm as an alternative to the existing Sieve of Eratosthenes. This modern algorithm offers better theoretical complexity O(n / log log n) and uses quadratic forms for prime detection. Features: - Comprehensive docstring with algorithm explanation - Type hints and input validation - Extensive doctests covering edge cases - Follows repository coding conventions * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * Fix: add missing newline at end of file * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * Delete pr_description.txt * Enhance documentation for Sieve of Atkin Added additional explanation about the Sieve of Atkin algorithm. --------- Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: Christian Clauss <cclauss@me.com>
1 parent 16e3b40 commit 3374ede

1 file changed

Lines changed: 110 additions & 0 deletions

File tree

maths/sieve_of_atkin.py

Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
"""
2+
Sieve of Atkin algorithm for finding all prime numbers up to a given limit.
3+
4+
The Sieve of Atkin is a modern variant of the ancient Sieve of Eratosthenes
5+
that is optimized for finding primes. It has better theoretical asymptotic
6+
complexity, especially for large ranges. This is the basic, non-segmented
7+
form.
8+
9+
Time Complexity: O(n / log log n)
10+
Space Complexity: O(n)
11+
12+
Reference: https://en.wikipedia.org/wiki/Sieve_of_Atkin
13+
"""
14+
15+
import math
16+
17+
18+
def sieve_of_atkin(limit: int) -> list[int]:
19+
"""
20+
Generate all prime numbers up to a given limit using the Sieve of Atkin.
21+
22+
The Sieve of Atkin is an optimized version of the Sieve of Eratosthenes.
23+
It uses a different set of quadratic forms to identify potential primes.
24+
25+
Args:
26+
limit: Upper bound for finding primes (inclusive)
27+
28+
Returns:
29+
List of prime numbers up to the given limit
30+
31+
Raises:
32+
ValueError: If limit is negative
33+
34+
Examples:
35+
>>> sieve_of_atkin(30)
36+
[2, 3, 5, 7, 11, 13, 17, 19, 23, 29]
37+
>>> sieve_of_atkin(10)
38+
[2, 3, 5, 7]
39+
>>> sieve_of_atkin(2)
40+
[2]
41+
>>> sieve_of_atkin(1)
42+
[]
43+
>>> sieve_of_atkin(0)
44+
[]
45+
>>> sieve_of_atkin(-5)
46+
Traceback (most recent call last):
47+
...
48+
ValueError: -5: Invalid input, please enter a non-negative integer.
49+
"""
50+
if limit < 0:
51+
msg = f"{limit}: Invalid input, please enter a non-negative integer."
52+
raise ValueError(msg)
53+
54+
if limit < 2:
55+
return []
56+
57+
# Initialize the sieve
58+
sieve = [False] * (limit + 1)
59+
60+
# Mark 2 and 3 as prime if they're within the limit
61+
if limit >= 2:
62+
sieve[2] = True
63+
if limit >= 3:
64+
sieve[3] = True
65+
66+
# Main algorithm - mark numbers using quadratic forms
67+
sqrt_limit = int(math.sqrt(limit)) + 1
68+
69+
for x in range(1, sqrt_limit):
70+
for y in range(1, sqrt_limit):
71+
# First quadratic form: 4x² + y²
72+
n = 4 * x * x + y * y
73+
if n <= limit and (n % 12 == 1 or n % 12 == 5):
74+
sieve[n] = not sieve[n]
75+
76+
# Second quadratic form: 3x² + y²
77+
n = 3 * x * x + y * y
78+
if n <= limit and n % 12 == 7:
79+
sieve[n] = not sieve[n]
80+
81+
# Third quadratic form: 3x² - y² (only when x > y)
82+
if x > y:
83+
n = 3 * x * x - y * y
84+
if n <= limit and n % 12 == 11:
85+
sieve[n] = not sieve[n]
86+
87+
# Remove squares of primes
88+
for r in range(5, sqrt_limit):
89+
if sieve[r]:
90+
square = r * r
91+
for i in range(square, limit + 1, square):
92+
sieve[i] = False
93+
94+
# Collect all primes
95+
primes = []
96+
for i in range(2, limit + 1):
97+
if sieve[i]:
98+
primes.append(i)
99+
100+
return primes
101+
102+
103+
if __name__ == "__main__":
104+
import doctest
105+
106+
doctest.testmod()
107+
108+
# Example usage
109+
print("Prime numbers up to 30 using Sieve of Atkin:")
110+
print(sieve_of_atkin(30))

0 commit comments

Comments
 (0)