GolfScript, 22/20 (20/19) bajtów
n(6?,:|2>{(.p|%-.}do:n
Kosztem prędkości kod może zostać skrócony o dwa bajty:
n(6?,:|2>.{|%2>-}/n*
Jeśli format wyjściowy określony w edytowanym pytaniu zostanie pominięty (co robi wiele istniejących odpowiedzi), dwa bajty można zapisać w szybkiej wersji, a jeden w wolniejszym:
n(6?,:|2>{(.p|%-.}do
n(6?,:|2>.{|%2>-}/`
Spowoduje to wydrukowanie dodatkowego LF po liczbach pierwszych dla wersji szybkiej i wydrukuje liczby pierwsze jako tablicę dla wersji wolnej.
Jak to działa
Obie wersje są implementacjami sita Eratostenesa .
Szybka wersja wykonuje następujące czynności:
Ustaw A = [ 2 3 4 … 999,999 ]
i | = [ 0 1 2 … 999,999 ]
.
Ustaw N = A[0]
i wydrukuj N
.
Zebrać wszystkie n-ty element z |
w C
. Są to wielokrotności N
.
Set A = A - C
.
Jeśli A
nie jest pusty, wróć do 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.
Wersja powolna działa w podobny sposób, ale zamiast sukcesywnego usuwania wielokrotności minimum „A” (co zawsze jest liczbą pierwszą), usuwa wielokrotności wszystkich liczb całkowitych dodatnich poniżej 1 000 000.
Konkurencyjność
W przypadku braku wbudowanych funkcji matematycznych do faktoryzacji lub sprawdzenia pierwszeństwa, wszystkie rozwiązania GolfScript będą albo bardzo duże, albo bardzo nieefektywne.
Choć wciąż daleko mi do wydajności, wydaje mi się, że osiągnąłem przyzwoity stosunek prędkości do wielkości. W chwili jego przedstawienia takie podejście wydaje się być najkrótsze z tych, które nie wykorzystują żadnego z wyżej wymienionych wbudowanych elementów. Mówię, wydaje się, ponieważ nie mam pojęcia, jak działają niektóre odpowiedzi ...
Dokonałem analizy porównawczej wszystkich czterech przesłanych rozwiązań GolfScript: w0lf (podział próbny), mojej drugiej odpowiedzi (twierdzenie Wilsona) i dwóch z tej odpowiedzi. Oto wyniki:
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)