Python problem 23 of 30

Sieve of Eratosthenes

  • Python
  • Medium

Write primes_up_to(n) that returns every prime number up to and including n. Do not test each number for divisors one at a time: use the sieve of Eratosthenes.

primes_up_to(30)
# [2, 3, 5, 7, 11, 13, 17, 19, 23, 29]

primes_up_to(1)   # []
Show hint

Start with a list of True values. For each prime p, cross out (set to False) every multiple of p. You can start crossing out at p * p.

Show solution
def primes_up_to(n):
    if n < 2:
        return []
    is_prime = [True] * (n + 1)
    is_prime[0] = is_prime[1] = False
    p = 2
    while p * p <= n:
        if is_prime[p]:
            for m in range(p * p, n + 1, p):
                is_prime[m] = False
        p += 1
    return [i for i, ok in enumerate(is_prime) if ok]

Any smaller multiple of p, such as 3p, was already crossed out by a smaller prime, so crossing out starts at p * p, and the outer loop can stop once p * p > n. The sieve runs in O(n log log n) time, which is close to linear.

Want a problem like this every day? See today's problem and keep a streak going.