Sieve: cross out composite numbers
Picture
Mark multiples of 2, then 3, then 5. Unmarked values remain prime.
Predict
Why can crossing multiples of p begin at p²?
Walk through the small example
Smaller multiples were handled earlier. Every composite has a small prime factor, and earlier primes already mark smaller multiples.
Mental model and complete Python solution
Instead of testing each number independently, let each discovered prime announce all numbers it disproves. Begin where that announcement contains new information.
What the function promises: Return all primes <= limit. Limits below two return an empty list.
def primes_through(limit):
if limit < 2: return []
prime = bytearray(b"\x01") * (limit+1)
prime[0:2] = b"\x00\x00"
p = 2
while p*p <= limit:
if prime[p]:
prime[p*p:limit+1:p] = b"\x00" * (((limit-p*p)//p)+1)
p += 1
return [i for i in range(2,limit+1) if prime[i]]
assert primes_through(20) == [2,3,5,7,11,13,17,19]
assert primes_through(1) == []
Work and storage: O(n log log n) time and O(n) bytes in the usual analysis.
When to recognize it: Every composite has a small prime factor, and earlier primes already mark smaller multiples.
Check before applying it: A full boolean array is unsuitable for enormous limits or narrow intervals far from zero.
Change one rule
Find primes only in [L,R] where R is huge but the interval is short.
See what changes
Use primes through √R to mark a segmented sieve over that interval.
Connect
invariants: Unmarked candidates have no processed prime divisor.
Fast power and modular arithmetic: Prime moduli enable additional algebraic tools, but only under stated conditions.