Кто-то из греков задался вопросом: можно ли вычислить очередное простое число, если известны все предыдущие? Например, исходя из того, что числа 1, 2, 3 и 5 простые, определить следующее простое число (7). Как ни мудрили мудрецы, такой формулы или алгоритма пока не придумали! Но усилия в этом направлении породили целые отрасли математики, – вот такой полезный неуспех!
Размышлял над задачей и грек Эратосфен. Он тоже не решил её, однако нашел остроумный способ отсеивать простые числа, не превышающие некоторого числа N. Вот суть его идеи.
Положим, мы ищем простые числа не превышающие 20. Выпишем на морском песочке в ряд числа с 1 до 20. Первые два числа – 1 и 2 – простые, их не тронем, а среди остальных сотрем каждое второе, то есть 4, 6, 8 и так далее.
Затем находим первое нестертое число – это три. Сотрем каждое третье после тройки: 6, 9, 12, 15 и 18 (хотя часть из них уже стерта, лишний раз это сделать не повредит). Повторяя процедуру, находим следующее нестертое число – это пять. Стираем каждое пятое после пятерки: 10, 15, 20 (хотя все они уже стерты). Достигнув середины этого списка – числа 11, остановимся. Дальше двигаться нет смысла, поскольку на песке остались лишь простые числа.
Вот результат этой пляжной математики, где стираемые числа выделены, а стертые обозначены звездочками. Здесь хватило всего двух просевов.
1-й отсев чисел, кратных 2:
1 2 3 4 5 6 7 8 9
2-й отсев чисел, кратных 3:
1 2 3 * 5 * 7 * 9 * 11 * 13 *
Результат – простые числа:
1 2 3 * 5 * 7 * * * 11 * 13 * * * 17 * 19 *
А если бы Эратосфен жил в наше время? Стал бы он царапать на песке? Конечно, нет, – на что ж тогда компьютеры? Программа «P_38_4» находит все простые числа, не превышающие 255, – роль песка исполняет множество чисел.
program P_38_4; { Решето Эратосфена }
var Simples : set of byte; { множество чисел }
n, m : integer;
F : text;
begin
Assign(F, 'P_38_4.out'); Rewrite(F);
Simples:= [2..255]; { Сначала множество полное }
{ Цикл вычеркивания составных чисел }
for n:=2 to (255 div 2) do begin
{ если число ещё не вычеркнуто }
if n in Simples then
{ проверяем на кратность ему все последующие }
for m:=2*n to 255 do
{ если остаток(m/n) равен нулю, то m – составное }
if (m mod n)=0
{ и его надо вычеркнуть из множества}
then Simples:= Simples – [m];
end;
{ Распечатка множества простых чисел }
for n:=2 to 255 do if n in Simples then Writeln(F,n);
Close(F); Readln;
end.