Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
109 changes: 109 additions & 0 deletions maths/sieve_of_atkin.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
"""
Sieve of Atkin algorithm for finding all prime numbers up to a given limit.

The Sieve of Atkin is a modern variant of the ancient Sieve of Eratosthenes
that is optimized for finding primes. It has better theoretical asymptotic
complexity, especially for large ranges.

Time Complexity: O(n / log log n)
Space Complexity: O(n)

Reference: https://en.wikipedia.org/wiki/Sieve_of_Atkin
"""

import math


def sieve_of_atkin(limit: int) -> list[int]:
"""
Generate all prime numbers up to a given limit using the Sieve of Atkin.

The Sieve of Atkin is an optimized version of the Sieve of Eratosthenes.
It uses a different set of quadratic forms to identify potential primes.

Args:
limit: Upper bound for finding primes (inclusive)

Returns:
List of prime numbers up to the given limit

Raises:
ValueError: If limit is negative

Examples:
>>> sieve_of_atkin(30)
[2, 3, 5, 7, 11, 13, 17, 19, 23, 29]
>>> sieve_of_atkin(10)
[2, 3, 5, 7]
>>> sieve_of_atkin(2)
[2]
>>> sieve_of_atkin(1)
[]
>>> sieve_of_atkin(0)
[]
>>> sieve_of_atkin(-5)
Traceback (most recent call last):
...
ValueError: -5: Invalid input, please enter a non-negative integer.
"""
if limit < 0:
msg = f"{limit}: Invalid input, please enter a non-negative integer."
raise ValueError(msg)

if limit < 2:
return []

# Initialize the sieve
sieve = [False] * (limit + 1)

# Mark 2 and 3 as prime if they're within the limit
if limit >= 2:
sieve[2] = True
if limit >= 3:
sieve[3] = True

# Main algorithm - mark numbers using quadratic forms
sqrt_limit = int(math.sqrt(limit)) + 1

for x in range(1, sqrt_limit):
for y in range(1, sqrt_limit):
# First quadratic form: 4x² + y²
n = 4 * x * x + y * y
if n <= limit and (n % 12 == 1 or n % 12 == 5):
sieve[n] = not sieve[n]

# Second quadratic form: 3x² + y²
n = 3 * x * x + y * y
if n <= limit and n % 12 == 7:
sieve[n] = not sieve[n]

# Third quadratic form: 3x² - y² (only when x > y)
if x > y:
n = 3 * x * x - y * y
if n <= limit and n % 12 == 11:
sieve[n] = not sieve[n]

# Remove squares of primes
for r in range(5, sqrt_limit):
if sieve[r]:
square = r * r
for i in range(square, limit + 1, square):
sieve[i] = False

# Collect all primes
primes = []
for i in range(2, limit + 1):
if sieve[i]:
primes.append(i)

return primes


if __name__ == "__main__":
import doctest

doctest.testmod()

# Example usage
print("Prime numbers up to 30 using Sieve of Atkin:")
print(sieve_of_atkin(30))
3 changes: 3 additions & 0 deletions pr_description.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
## Summary
This PR adds an implementation of the **Sieve of Atkin** algorithm to the maths directory...