GolfScript, 22/20 (20/19) байт
n(6?,:|2>{(.p|%-.}do:n
За ціною швидкості код можна зробити на два байти коротше:
n(6?,:|2>.{|%2>-}/n*
Якщо вихідний формат, зазначений у відредагованому запитанні, не враховується (саме це робить багато існуючих відповідей), у швидкій версії можуть бути збережені два байти, а один у повільній:
n(6?,:|2>{(.p|%-.}do
n(6?,:|2>.{|%2>-}/`
Це надрукує додатковий LF після прайметів для швидкої версії, а також друкує праймери як масив для повільної.
Як це працює
Обидві версії є реалізацією сита Ератосфена .
Швидка версія робить наступне:
Встановити A = [ 2 3 4 … 999,999 ]
і | = [ 0 1 2 … 999,999 ]
.
Встановити N = A[0]
та роздрукувати N
.
Зібрати кожен N-й елемент з |
вC
. Це множини N
.
Встановити A = A - C
.
Якщо A
це не порожньо, поверніться до 2.
n(6? # Push "\n".pop() ** 6 = 1,000,000.
,:| # Push | = [ 0 1 2 … 999,999 ].
,2> # Push A = [ 2 3 4 … 999,999 ].
{ #
( # Unshift the first element (“N”) of “A”.
.p # Print “N”.
|% # Collect every N-th element from “A” into a new array, starting with the first.
- # Take the set difference of “A” and the array from above.
. # Duplicate the set difference.
}do # If the set difference is non-empty, repeat.
:n # Store the empty string in “n”, so no final LF will get printed.
Повільна версія працює аналогічно, але замість послідовного видалення кратних мінімумів "A" (що завжди є простим), вона видаляє кратні всі додатні цілі числа нижче 1 000 000.
Конкурентоспроможність
За відсутності будь-яких вбудованих математичних функцій для факторизації або перевірки первинності, всі рішення GolfScript будуть або дуже великими, або дуже неефективними.
Хоча я ще далеко не ефективний, я думаю, що я досяг гідного співвідношення швидкості та розміру. На момент його подання цей підхід здається найкоротшим із тих, у яких не використовується жоден із згаданих вище вбудованих модулів. Я кажу, здається тому що я не маю уявлення, як працюють деякі відповіді ...
Я порівняв усі чотири представлені рішення GolfScript: w0lf's (пробний поділ), інша моя відповідь (теорема Вілсона) та два відповіді. Такі результати:
Bound | Trial division | Sieve (slow) | Wilson's theorem | Sieve (fast)
----------+--------------------+--------------------+------------------+----------------
1,000 | 2.47 s | 0.06 s | 0.03 s | 0.03 s
10,000 | 246.06 s (4.1 m) | 1.49 s | 0.38 s | 0.14 s
20,000 | 1006.83 s (16.8 m) | 5.22 s | 1.41 s | 0.38 s
100,000 | ~ 7 h (estimated) | 104.65 (1.7 m) | 35.20 s | 5.82 s
1,000,000 | ~ 29 d (estimated) | 111136.97s (3.1 h) | 3695.92 s (1 h) | 418.24 s (7 m)