Это не совсем то, о чем вы спрашиваете, но вот более идиоматическая (и гораздо более быстрая) версия Sieve.
По сути, вам нужно проверить, какое число является кратным. Вы можете получить это из таблицы модулей: |/~
l =: 2 3 4 5 7 21 45 49 61
|/~ l
0 1 0 1 1 1 1 1 1
2 0 1 2 1 0 0 1 1
2 3 0 1 3 1 1 1 1
2 3 4 0 2 1 0 4 1
2 3 4 5 0 0 3 0 5
2 3 4 5 7 0 3 7 19
2 3 4 5 7 21 0 4 16
2 3 4 5 7 21 45 0 12
2 3 4 5 7 21 45 49 0
Каждая пара кратных дает 0
на столе. Теперь нас не интересуют 0
, соответствующие собственным модулям (2 по модулю 2, 3 по модулю 3 и т. д.; 0
по диагонали), поэтому мы должны их удалить. Один из способов сделать это — добавить вместо них 1
, например:
=/~ l
1 0 0 0 0 0 0 0 0
0 1 0 0 0 0 0 0 0
0 0 1 0 0 0 0 0 0
0 0 0 1 0 0 0 0 0
0 0 0 0 1 0 0 0 0
0 0 0 0 0 1 0 0 0
0 0 0 0 0 0 1 0 0
0 0 0 0 0 0 0 1 0
0 0 0 0 0 0 0 0 1
(=/~l) + (|/~l)
1 1 0 1 1 1 1 1 1
2 1 1 2 1 0 0 1 1
2 3 1 1 3 1 1 1 1
2 3 4 1 2 1 0 4 1
2 3 4 5 1 0 3 0 5
2 3 4 5 7 1 3 7 19
2 3 4 5 7 21 1 4 16
2 3 4 5 7 21 45 1 12
2 3 4 5 7 21 45 49 1
Это также может быть записано как (=/~ + |/~) l
.
Из этой таблицы мы получаем окончательный список чисел: каждое число, столбец которого содержит 0
, исключается.
Мы строим этот список исключений, просто умножая его на столбец. Если столбец содержит 0
, его произведение равно 0
, в противном случае это положительное число:
*/ (=/~ + |/~) l
256 2187 0 6250 14406 0 0 0 18240
Прежде чем сделать последний шаг, нам нужно немного улучшить это. Нет причин выполнять длинные умножения, так как нас интересуют только 0
s и not-0
s. Итак, при построении таблицы мы сохраним только 0
s и 1
s, взяв "знак" каждого числа (это signum
:*
):
* (=/~ + |/~) l
1 1 0 1 1 1 1 1 1
1 1 1 1 1 0 0 1 1
1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 0 1 1
1 1 1 1 1 0 1 0 1
1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1
so,
*/ * (=/~ + |/~) l
1 1 0 1 1 0 0 0 1
Из списка исключений вы просто добавляете copy
:#
числа в свой окончательный список:
l #~ */ * (=/~ + |/~) l
2 3 5 7 61
or,
(]#~[:*/[:*=/~+|/~) l
2 3 5 7 61
person
Eelvex
schedule
29.11.2012