AWK-129バイト
...大丈夫...コンパクトさのためにポイントを獲得するには長すぎます...しかし、多分それはスピードのためにいくらかの名誉を得ることができますか?
x
ファイル:
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++}}
ランニング:
$ 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
読みやすい:
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++
}
}
このプログラムはL
、「数値のテープ」として使用して素数のストリームを計算し、見つかった素数が飛び跳ねL
て、除数を持つことが既に知られている近くの数にフラグを立てます。これらのジャンププライムは、「数字のテープ」L
が最初からます。
L[n]
空のテープヘッドを切り落とすことは、既知の(プライム)除数がないことを意味します。
L[n]
値を保持すると、この値は素数であり、除算することが知られていますn
。
したがって、素数の除数または新しい素数を見つけました。その後、このプライムはL[n+m*p]
、テープが空であることがわかった次のプライムに進みます。
これは、エラトステネスのふるいが「クラインのボトルを通して引っ張られた」ようなものです。あなたは常にテープの開始時に行動します。テープから複数の素数を発射する代わりに、自由な位置が見つかるまでテープから離れるカーソルが独自の値の複数の距離だけ開始するので、すでに見つかっている素数を使用します。
外側のループはループごとに1つの素数決定または素数決定を生成しますが、見つかった素数はカウントされP
てキーとして保存されますが、この(key、value)ペアの値はプログラムフローには関係ありません。
それらのキーi
がP
既に(i in P
)にある場合、p(p(i))品種の素数があります。
ランニング:
$ time awk -f x.awk | wc -l
10000
real 0m3.675s
user 0m3.612s
sys 0m0.052s
このコードは、事前に計算された外部のプライムテーブルを使用しないことを考慮してください。
私の古き良きThinkpad T60にかかった時間ですので、すぐに呼ばれるに値すると思います。
Debian8 / AMD64 mawk
を使用gawk
してテスト済み