AWK - 129 octets
... ouais ... trop longtemps pour gagner des points pour la compacité ... mais peut-être peut-il gagner un peu d'honneur pour la vitesse?
Le x
dossier:
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++}}
Fonctionnement:
$ 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
Lisible:
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++
}
}
Le programme calcule un flux de nombres premiers en utilisant une L
«bande de nombres» contenant des nombres premiers sautant L
pour signaler les nombres voisins déjà connus pour avoir un diviseur. Ces nombres premiers sautants avancent tandis que la «bande de nombres» L
est coupée numéro par numéro depuis son début.
Le fait de couper la tête de bande L[n]
étant vide signifie qu'il n'y a pas de diviseur (principal) connu.
L[n]
détenir une valeur signifie que cette valeur est un nombre premier et connu pour se diviser n
.
Donc, soit nous avons trouvé un diviseur premier, soit un nouveau premier. Ensuite, ce nombre sera avancé au suivant L[n+m*p]
sur la bande trouvée vide.
C'est comme le tamis d'Eratosthène "tiré à travers une bouteille de Klein". Vous agissez toujours sur le début de la bande. Au lieu de tirer des multiples de nombres premiers à travers la bande, vous utilisez les nombres premiers déjà trouvés comme curseurs sautant loin du début de la bande par plusieurs distances de leur propre valeur jusqu'à ce qu'une position libre soit trouvée.
Alors que la boucle externe génère une décomposition principale ou non principale par boucle, les nombres premiers trouvés sont comptés et stockés sous P
forme de clé, la valeur de cette paire (clé, valeur) n'est pas pertinente pour le flux du programme.
Si leur clé i
se trouve P
déjà dans ( i in P
), nous avons un premier de la race p (p (i)).
Fonctionnement:
$ time awk -f x.awk | wc -l
10000
real 0m3.675s
user 0m3.612s
sys 0m0.052s
Tenez compte du fait que ce code n'utilise pas de tables principales précalculées externes.
Du temps pris sur mon bon vieux Thinkpad T60, donc je pense qu'il mérite d'être appelé rapidement.
Testé avec mawk
et gawk
sur Debian8 / AMD64