GolfScript, 22/20 (20/19) bytes
n(6?,:|2>{(.p|%-.}do:n
À custa da velocidade, o código pode ser reduzido em dois bytes:
n(6?,:|2>.{|%2>-}/n*
Se o formato de saída especificado na pergunta editada for desconsiderado (que é o que muitas das respostas existentes fazem), dois bytes podem ser salvos na versão rápida e um na versão lenta:
n(6?,:|2>{(.p|%-.}do
n(6?,:|2>.{|%2>-}/`
Isso imprimirá um LF adicional após os primos da versão rápida e os primos como uma matriz do lento.
Como funciona
Ambas as versões são implementações da peneira de Eratóstenes .
A versão rápida faz o seguinte:
Conjunto A = [ 2 3 4 … 999,999 ]
e | = [ 0 1 2 … 999,999 ]
.
Conjunto N = A[0]
e imprimir N
.
Colete todos os N-ésimos elementos de |
dentro C
. Estes são os múltiplos de N
.
Set A = A - C
.
Se A
não estiver vazio, volte para 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 versão lenta funciona de maneira semelhante, mas, em vez de remover sucessivamente múltiplos do mínimo de "A" (que é sempre primo), remove múltiplos de todos os números inteiros positivos abaixo de 1.000.000.
Competitividade
Na ausência de funções matemáticas embutidas para fatorar ou verificar a primalidade, todas as soluções GolfScript serão muito grandes ou muito ineficientes.
Embora ainda esteja longe de ser eficiente, acho que atingi uma proporção decente de velocidade / tamanho. No momento da submissão, essa abordagem parece ser a mais curta entre as que não usam nenhum dos embutidos mencionados acima. Eu digo parece que não tenho ideia de como algumas das respostas funcionam ...
Comparei todas as quatro soluções GolfScript enviadas: w0lf (divisão de teste), minha outra resposta (teorema de Wilson) e as duas respostas. Estes foram os resultados:
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)