Курс по Raku / Приложение 🆕 / Всичко наедно / Смесени мини проекти / Exercises / Решето на Ератостен
Решение: Решето на Ератостен
Ето едно възможно решение на задачата.
Код
my $limit = 30;
my %composite;
for 2 .. $limit -> $i {
next if %composite{$i};
for ($i², $i² + $i ... $limit) -> $multiple {
%composite{$multiple} = True;
}
}
say (2..$limit).grep({ !%composite{$_} });🦋 Намерете програмата във файла sieve.raku.
Изход
(2 3 5 7 11 13 17 19 23 29)Коментари
Вместо списък от флагове,
%compositeпомни кои числа са зачеркнати. Число, което още липсва в него, когато дойде редът му, е просто.За всяко просто
$iкратните му се пораждат като последователността$i², $i² + $i ... $limitи се отбелязват като съставни. Започването от$i²прескача кратните, вече обработени от по-малки прости числа.Това е една-единствена последователност, а не заглавие на цикъл
forв стил C. Операторът...взема първите две стойности, изчислява стъпката между тях и продължава до границата. За$i=3това означава започване от9, после12, значи стъпката е3, и цикълът обхожда целия списък:my $i = 3; say ($i², $i² + $i ... 30); # (9 12 15 18 21 24 27 30)
Значи
forполучава един списък за обхождане —9, 12, 15, …, — а не три отделни клаузи.$i²повдига числото на квадрат с горен индекс от Unicode. Raku приема и трите записа —$i * $i,$i ** 2и$i²: те изчисляват точно една и съща стойност, така че изберете онзи, който ви се чете най-добре. Цифрите за горен индекс (²,³, …) са обикновени знаци, които можете да наберете или поставите направо в изходния код.