これは私の最初のコードゴルフの質問であり、非常に簡単な質問です。コミュニティガイドラインに違反した可能性がある場合は、事前に謝罪します。
タスクは、100万未満のすべての素数を昇順で印刷することです。出力形式は、出力の行ごとに1つの数字にする必要があります。
目的は、ほとんどのコードゴルフの提出と同様に、コードサイズを最小限にすることです。ランタイムの最適化もボーナスですが、副次的な目的です。
10^6
、もっと短いからです;)
1e6
:-D
これは私の最初のコードゴルフの質問であり、非常に簡単な質問です。コミュニティガイドラインに違反した可能性がある場合は、事前に謝罪します。
タスクは、100万未満のすべての素数を昇順で印刷することです。出力形式は、出力の行ごとに1つの数字にする必要があります。
目的は、ほとんどのコードゴルフの提出と同様に、コードサイズを最小限にすることです。ランタイムの最適化もボーナスですが、副次的な目的です。
10^6
、もっと短いからです;)
1e6
:-D
回答:
比較のためだけに:
Prime@Range@78498
コメントで述べたように、1行につき1つの素数を提供できませんでした。補正:
Column@Prime@Range@78498
Prime~Array~78498
また17 :)
Print/@
と終了で、8文字余分にコストがかかります。;
Null
k=P=1
while k<1e6:P%k and print(k);P*=k*k;k+=1
ループがテストk
に到達するまでに、二乗要因を繰り返し計算しましたP=(k-1)!^2
。k
が素数である場合、積は表示され1 * 2 * ... * (k-1)
ないため、の要因ではありませんP
。しかし、それが複合材料である場合、その主な要因はすべて製品内で小さくなります。平方は、実際k=4
にはプライムと呼ばれるのを止めるためにのみ必要です。
より強く、ウィルソンの定理から、いつk
が素数であるかP%k
はに等しいことがわかり1
ます。ここで必要なのはゼロ以外の値だけですが、一般的にP%k
は、それk
が素数であるかどうかの指標変数です。
SEG-FAULT
印刷後881
-O3
しgcc
て問題を解決しました!!
n=2;main(m){n<1e6&&main(m<2?printf("%d\n",n),n:m-++n%m);}
seq 2 1e6|factor|sed 's/.*: //g;/ /d'
seq 2 1000000|factor|sed -e 's/[0-9]*: //g' -e '/^.* .*$/ d'
私のコンピューター(2.0 GHz CPU、2 GB RAM)では14秒かかります。
seq 2 1000000|factor|sed 's/[0-9]*: //g;/^.* .*$/ d'
seq 1e6|factor|awk '$0=$2*!$3'
少し短いです。
c p
、cがcatへのシンボリックリンクであり、pが100万までの素数を持つテキストファイルである場合もあります。シェル組み込みコマンドで実行できますか?
saeednは私の提案(彼のアプローチよりも短くて速い)に基づいて行動しないので、私は自分の答えを投稿したいと思いました。
seq 1e6|factor|awk '$0=$2*!$3'
seq 1e6
最大1,000,000までのすべての正の整数をリストします。
factor
それらを一つずつ因数分解します。最初の10の出力は次のとおりです。
1:
2: 2
3: 3
4: 2 2
5: 5
6: 2 3
7: 7
8: 2 2 2
9: 3 3
10: 2 5
最後に、
awk '$0=$2*!$3'
行全体($0
)を2番目のフィールド(最初の素因数)と3番目のフィールドの論理否定の積に変更します(1
それが1つの素因数以下の0
場合)。
これにより、素数に対応する行が数値自体に置き換えられ、他のすべての行がゼロに置き換えられます。awkは真理値のみを出力するため、素数のみが出力されます。
awk '$0=$2*!$3'
かっこいい!
require'mathn'
p (2..1e6).select &:prime?
.to_a
れているため、必要はありませんselect
。また、Symbol#to_procの短縮表記を使用して、さらに短縮することもできます。p (2..1e6).select &:prime?
(1は素数ではありません)
require'prime';p Prime.take 78498
。
できればもっとゴルフします...
このほとんどは、factor
の厄介な出力形式を解析しようとしています。
seq 1e6|factor|grep -oP "(?<=: )\d+$"
私のマシンで5.7秒ほどで完了します。
(たまたま私の投稿が2ページ目の回答の最初のページであったため、だれもそれを見ることはありません...)
これは長く、遅くなります(10秒かかります)。
seq 1e6|factor|egrep ':.\S+$'|grep -oE '\S+$'
factor
前に出会ったことはありませんが、coreutilsにあります!
seq 1e6|factor|grep -oP "(?<=: )\d+$"
のperl-はgrepの後読みで
for k in range(2,10**6):
if all(k%f for f in range(2,k)):print(k)
エラトステネスのふるいに基づいています。
p=[];z=range(2,10**6)
while z:f=z[0];p+=[f];z=[k for k in z if k%f]
for k in p:print(k)
0
し1
ます。代わりにを使用して、これを修正できますrange(2,10**6)
。また、if
ステートメントはoutとは別の行にあるfor
必要があります。そうしないと、エラーが発生します。
mapM print [n|n<-[2..10^6],all((>0).rem n)[2..n-1]]
mapM_
にmapM
、戻り値は印刷されませんが、これはコードのゴルフです。;)
p~,p∘.×p←1↓⍳1e6
私の通訳はメモリの問題に遭遇しましたが、理論的には機能します。
⍪
行ごとに1つの番号を作成するために前にが必要であり、を必要としません,
。
⍳
は最初の整数です。1↓
最初のものをドロップします。p←
pに割り当てます。p∘.×p
乗算表を作成します。p~
pから右側にあるものをすべて削除します。(,
必要ではありません。テーブルをリストに分解します。)
正規表現のカンフー:)
for(1..1E6){(1x$_)=~/^(11+?)\1+$/ or print"$_\n"}
ゴルフされていないバージョン:
for(1 .. 1_000_000) {
(1x$_) =~ /^(11+?)\1+$/ or print "$_\n";
}
この投稿を入力している間、10%も進歩していません!
正規表現のソース:http : //montreal.pm.org/tech/neil_kandalgaonkar.shtml
1000000
書くことができます10**6
私はこれがMathematicaを破ったとは信じられません(たとえそれがたった1文字x 2文字であっても)
a#~1 p:a=:i.1e6
または:
p:i.78498
... The output format should be one number per line of output.
それが私の答えがで始まる理由1[\
です。
n(6?,:|2>{(.p|%-.}do:n
速度を犠牲にして、コードを2バイト短くすることができます。
n(6?,:|2>.{|%2>-}/n*
編集された質問で指定された出力形式を無視する場合(これは既存の回答の多くが行うことです)、高速バージョンでは2バイト、低速バージョンでは1バイトを保存できます。
n(6?,:|2>{(.p|%-.}do
n(6?,:|2>.{|%2>-}/`
これは、高速バージョンの素数の後に追加のLFを出力し、低速バージョンの素数を配列として出力します。
両方のバージョンは、エラトステネスのふるいの実装です。
高速バージョンは次のことを行います。
設定A = [ 2 3 4 … 999,999 ]
し| = [ 0 1 2 … 999,999 ]
ます。
設定N = A[0]
して印刷しますN
。
からすべてのN番目の要素を収集|
しC
ます。これらはの倍数ですN
。
設定しA = A - C
ます。
A
空でない場合は、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」の倍数(常に素数)を連続して削除する代わりに、1,000,000未満のすべての正の整数の倍数を削除します。
素因数分解またはチェックする組み込み数学関数がない場合、すべてのGolfScriptソリューションは非常に大きいか、非常に非効率的です。
まだ効率的とはほど遠いですが、私はまともな速度対サイズ比を達成していると思います。提出時点では、このアプローチは前述の組み込みのいずれも使用していないアプローチの中で最も短いようです。私が言っているようだ、私は答えの一部がどのように機能するか分からないので...
提出された4つのGolfScriptソリューションすべてをベンチマークしました:w0lf(トライアル部門)、他の回答(Wilsonの定理)、およびこの回答の2つ。これらは結果でした:
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)
10 6?,{:x,{)x\%!},,2=},`
古いコード:
10 6?,{.,{)\.@%!},,2=*},`
このコードは、信じられないほど遅く、非効率的であるため、理論的な価値しかありません。実行には数時間かかると思います。
あなたがそれをテストしたいなら、例えば100までの素数だけを試してください:
10 2?,{:x,{)x\%!},,2=},`
\;
でキャラクターを保存できます*
。(また、最初の除数を見つけるのではなく、それらのすべてで現在の文字カウントのためにはるかに高速に取得することができます:10 6?,2>{.),2>{1$\%!}?=},`
.,
と:x,
して\.@
とx\
(空白があるため、コメントにMDの問題をエスケープするのである)、および削除します*
。
!10 6?,2>{.(@*.)@%!},n*\;
編集された質問で指定された出力形式が無視される場合、1バイトを保存できます。
!10 6?,2>{.(@*.)@%!},`\;
これにより、プライムは1行に1つではなく、配列として(他の多くのソリューションと同様に)印刷されます。
一般的な考え方は、使用することですウィルソンの定理と述べ、nは > 1が素数であるとし、場合にだけ
! # Push the logical NOT of the empty string (1). This is an accumulator.
10 6? # Push 10**6 = 1,000,000.
,2> # Push [ 2 3 4 … 999,999 ].
{ # For each “N” in this array:
.( # Push “N - 1”.
@ # Rotate the accumulator on top of the stack.
* # Multiply it with “N - 1”. The accumulator now hold “(N - 1)!”.
.) # Push “(N - 1)! + 1”
@ # Rotate “N” on top of the stack.
%! # Push the logical NOT of “((N - 1)! + 1) % N”.
}, # Collect all “N” for which “((N - 1)! + 1) % N == 0” in an array.
n* # Join that array by LF.
\; # Discard the accumulator.
トライアル部門よりは速いが、エラトステネスのふるいよりは遅い。私の他の答えをご覧ください。
void x(){for(int i=1;i++<1e6;)System.out.print(new String(new char[i]).matches(".?|(..+?)\\1+")?"":(i+"\n"));}
素数性テストとして正規表現による単項除算を使用します。
main(i,j,b){for(;i++<1e6;b++&&printf("%d\n",i))for(j=2;j<i;)b=i%j++&&b;}
アルゴリズムはひどく非効率的ですが、コードゴルフをしているので問題ではありません。
main(i,j,b){for(;i++<1e6;b++&&printf("%d\n",i))for(j=2;j<i;)b=i%j++&&b;}
または、このようなアイデア(実際にコンパイルしなかったため)
i
0になるのでしょうか?私はあなたが提供する場合は、と思うの任意の引数を、それは失敗します。また、j
何らかのタイプのエラーがあると思います。しかし、よくわかりませんb
。
for(i in 2:1e6)if(sum(!i%%2:i)<2)cat(i," ")
2から1e6までの各数値xについて、0に等しいx mod 2からxの数が2未満の場合、単純に出力します。
私の(それほど賢くない)試みは、ファクターを使用して製品をファクタリングすることでした。
factor ${PRODUCT}
残念ながら、多数の製品はもちろん巨大です。また、実行に12時間以上かかりました。私はそれがユニークだと思ったので、私はそれを投稿することにしました。
6未満の素数であれば、それは合理的です。
factor 30
まあ、私は試しました。
factor
は、基本的な試行除算アルゴリズムよりも最適化されたパフォーマンスがはるかに悪い例です。
Enumerable.Range(1,1e6).Where(n=>Enumerable.Range(2,n).All(x=>x%n!=0))
長い間ここではあまり見ないでしょう...
double
1e6
が、int
ではint
必須ですRange
。(2)内部には、Range
最大でも取る必要がありn-2
そうでないかをテストします、用語n % n
明らかにしています0
。(3)x%n
必要なときに書き込みますn%x
。これらの問題を修正すると、次のように機能します。Enumerable.Range(2,999999).Where(n=>Enumerable.Range(2,n-2).All(x=>n%x!=0))
ただし、これでも数値は出力されません。要件は1行に1つでした。