Skip to content

Commit 86b4b59

Browse files
committed
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
1 parent 0ee534e commit 86b4b59

File tree

1 file changed

+109
-0
lines changed

1 file changed

+109
-0
lines changed

maths/sieve_of_atkin.py

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

0 commit comments

Comments
 (0)