AWK - 129 byte
... oookay ... troppo tempo per guadagnare punti per compattezza ... ma forse può guadagnare un po 'di onore per la velocità?
Il x
file:
BEGIN{n=2;i=0;while(n<1366662){if(n in L){p=L[n];del L[n]}else{P[p=n]=++i;if(i in P)print n}j=n+p;while(j in L)j=j+p;L[j]=p;n++}}
In esecuzione:
$ awk -f x | nl | tail
9991 1365913
9992 1365983
9993 1366019
9994 1366187
9995 1366327
9996 1366433
9997 1366483
9998 1366531
9999 1366609
10000 1366661
Leggibile:
BEGIN {
n=2
i=0
while( n<1366662 ) {
if( n in L ) {
p=L[n]
del L[n]
} else {
P[p=n]=++i
if( i in P ) print n
}
j=n+p
while( j in L ) j=j+p
L[j]=p
n++
}
}
Il programma calcola un flusso di numeri primi usando L
come "nastro di numeri" tenendo in mano i numeri primi saltando su L
per contrassegnare i numeri vicini già noti per avere un divisore. Questi numeri primi che saltano avanzeranno mentre il "nastro di numeri" L
viene tagliato numero per numero dall'inizio.
Mentre tagliare la testina del nastro L[n]
essendo vuota significa che non esiste un divisore (primo) noto.
L[n]
detenere un valore significa che questo valore è un numero primo e noto per dividere n
.
Quindi o abbiamo trovato un divisore primo o un nuovo primo. Quindi il primo verrà spostato al successivo L[n+m*p]
sul nastro trovato vuoto.
Questo è come il setaccio di Eratostene "tirato attraverso una bottiglia di Klein". Agisci sempre all'inizio del nastro. Invece di sparare multipli di numeri primi attraverso il nastro, usi i numeri primi già trovati mentre i cursori che saltano via dal nastro iniziano per più distanze del loro stesso valore fino a quando non viene trovata una posizione libera.
Mentre il ciclo esterno genera una decisione principale o meno per ciclo, i numeri primi trovati vengono contati e memorizzati P
come chiave, il valore di questa coppia (chiave, valore) non è rilevante per il flusso del programma.
Se la loro chiave si i
trova P
già in ( i in P
), abbiamo un numero primo della razza p (p (i)).
In esecuzione:
$ time awk -f x.awk | wc -l
10000
real 0m3.675s
user 0m3.612s
sys 0m0.052s
Tenere presente che questo codice non utilizza tabelle primi precalcolate esterne.
Tempo impiegato sul mio buon vecchio Thinkpad T60, quindi penso che meriti di essere chiamato velocemente.
Testato con mawk
e gawk
su Debian8 / AMD64