Skip to content
70 changes: 70 additions & 0 deletions maths/optimised_sieve_of_eratosthenes.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
# Optimized Sieve of Eratosthenes: An efficient algorithm to compute all prime numbers
# up to limit. This version skips even numbers after 2, improving both memory and time
# usage. It is particularly efficient for larger limits (e.g., up to 10**8 on typical
# hardware).
# Wikipedia URL - https://en.wikipedia.org/wiki/Sieve_of_Eratosthenes

from math import isqrt


def optimized_sieve(limit: int) -> list[int]:
"""
Compute all prime numbers up to and including `limit` using an optimized
Sieve of Eratosthenes.

This implementation skips even numbers after 2 to reduce memory and
runtime by about 50%.

Parameters
----------
limit : int
Upper bound (inclusive) of the range in which to find prime numbers.
Expected to be a non-negative integer. If limit < 2 the function
returns an empty list.

Returns
-------
list[int]
A list of primes in ascending order that are <= limit.

Examples
--------
>>> optimized_sieve(10)
[2, 3, 5, 7]
>>> optimized_sieve(1)
[]
>>> optimized_sieve(2)
[2]
>>> optimized_sieve(30)
[2, 3, 5, 7, 11, 13, 17, 19, 23, 29]
>>> optimized_sieve(0)
[]
"""
if limit < 2:
return []

# Handle 2 separately
primes = [2]

# Only odd numbers from 3 to limit
size = (limit - 1) // 2
is_prime = [True] * (size + 1)
bound = isqrt(limit)

for i in range((bound - 1) // 2 + 1):
if is_prime[i]:
p = 2 * i + 3
# Start marking from p^2, converted to index
start = (p * p - 3) // 2
for j in range(start, size + 1, p):
is_prime[j] = False

primes.extend(2 * i + 3 for i in range(size + 1) if is_prime[i])
return primes


if __name__ == "__main__":
import doctest

doctest.testmod()
print(optimized_sieve(50))
Loading