Решето Эратосфена

Самый красивый способ найти все простые числа до заданной границы — вычеркнуть лишнее.

Простое число — натуральное число больше единицы, у которого ровно два делителя: единица и оно само.

Простые числа — это «атомы» арифметики. Любое натуральное число больше единицы либо само простое, либо однозначно раскладывается в произведение простых: $60 = 2^2 \cdot 3 \cdot 5$. Это утверждение называют основной теоремой арифметики, и именно оно делает простые числа фундаментом всей теории чисел. Прежде чем изучать их свойства, надо научиться их находить — и тут нам поможет идея, которой больше двух тысяч лет.

Зачем вычёркивать, а не делить

Наивный способ проверить число $n$ на простоту — перебрать все возможные делители. Но если нам нужны все простые до миллиона, проверять каждое по отдельности расточительно. Эратосфен Киренский, живший в III веке до нашей эры, придумал приём наоборот: вместо того чтобы спрашивать «простое ли каждое число?», он предложил вычёркивать заведомо составные.

Идея проста до гениальности. Выпишем все числа от 2 до $N$. Берём первое невычеркнутое число — это 2, оно простое. Вычёркиваем все его кратные: 4, 6, 8, … Следующее невычеркнутое — 3, тоже простое; вычёркиваем 6, 9, 12, … И так далее. То, что осталось невычеркнутым, — простые числа.

Решето в коде

Запустите и убедитесь сами:

def sieve(n):
    is_prime = [True] * (n + 1)
    is_prime[0] = is_prime[1] = False
    p = 2
    while p * p <= n:
        if is_prime[p]:
            for multiple in range(p * p, n + 1, p):
                is_prime[multiple] = False
        p += 1
    return [i for i in range(2, n + 1) if is_prime[i]]

primes = sieve(50)
print("Простые до 50:", primes)
print("Сколько их:", len(primes))

Вывод:

Простые до 50: [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47]
Сколько их: 15

Как работает под капотом

Два момента делают решето быстрым. Во-первых, вычёркивание кратных начинаем не с $2p$, а с $p^2$: все меньшие кратные ($2p, 3p, \dots$) уже вычеркнуты предыдущими простыми. Во-вторых, внешний цикл идёт лишь пока $p^2 \le N$, то есть до $\sqrt{N}$. Если бы у числа $n \le N$ был делитель больше $\sqrt{N}$, то парный к нему делитель был бы меньше $\sqrt{N}$ и число уже было бы вычеркнуто.

Суммарное число операций оценивается величиной

$$\sum_{p \le N,\; p \text{ простое}} \frac{N}{p} \approx N \ln \ln N,$$

то есть почти линейно по $N$ — отсюда и репутация «очень быстрого» алгоритма. Сравните с наивной проверкой каждого числа делением до корня: там получается порядка $N \sqrt{N}$ операций.

Частые ошибки

Первая ловушка — забыть, что 0 и 1 не простые: единица имеет лишь один делитель, и если её посчитать простой, рухнет однозначность разложения. Вторая — стартовать вычёркивание с $2p$ вместо $p^2$: код останется верным, но потеряет в скорости. Третья — спутать «простое» и «нечётное»: 9 нечётно, но составно ($9 = 3 \cdot 3$), а 2 — единственное чётное простое.

Итог

  • Простое число имеет ровно два делителя; 1 — не простое.
  • Решето Эратосфена вычёркивает кратные каждого найденного простого.
  • Достаточно перебирать $p$ до $\sqrt{N}$ и вычёркивать с $p^2$.
  • Сложность около $N \ln \ln N$ — практически линейна.
Проверьте себя
1. Почему во внешнем цикле решета достаточно дойти лишь до $\sqrt{N}$?
AТак быстрее, но результат становится приближённым
BУ любого составного $n \le N$ есть делитель не больше $\sqrt{N}$, поэтому оно уже вычеркнуто
CПростых чисел больше $\sqrt{N}$ не бывает
DЭто случайное ограничение, можно идти и до $N$
2. Почему вычёркивание кратных простого $p$ начинают с $p^2$, а не с $2p$?
AЧтобы не выйти за границу массива
BЧисла $2p, 3p, \dots, (p-1)p$ уже вычеркнуты меньшими простыми
CИначе пропустятся некоторые простые
DЭто ускоряет, но даёт неверный ответ
3. Какое из чисел НЕ является простым?
A2
B17
C1
D23