このCコードを小さくすることは可能ですか?0から1000までのすべての素数を出力します。
C、89文字
int i,p,c;for(i=2;i<1e3;i++){c=0;for(p=2;p<i;p++)if(i%p==0)c++;if(c==0)printf("%u\n",i);}
このCコードを小さくすることは可能ですか?0から1000までのすべての素数を出力します。
C、89文字
int i,p,c;for(i=2;i<1e3;i++){c=0;for(p=2;p<i;p++)if(i%p==0)c++;if(c==0)printf("%u\n",i);}
回答:
59 57バイト
@feersumソリューションに基づくが、素数性チェックをさらに進めることができる
for(int p=1,d;d=p++%999;d||printf("%d\n",p))for(;p%d--;);
Runer112のコメントに基づいて編集
d=p++%999
。そうでなければ、これはかなり気密なゴルフの仕事に見えます!
(私はこれをCの整数のサイズ制限を実現しないように書いたので、コードを短縮するのに実際には役に立たない可能性があります。)
まず、アルゴリズムについて一言。コードをゴルフする前に、結果を得るための最善の全体的な戦略について考える必要があります。
あなたは試験分割を行うことによって素数性をチェックしています-の各潜在的な除数p
をテストしていますi
。2つのループが必要になるため、文字数が多くなります。したがって、ループなしで素数性をテストすると、文字が節約される可能性があります。
多くの場合、短いアプローチが使用するウィルソンの定理:数がn
素数であると場合にだけ
fact(n-1)%n == n-1
どこfact
階乗関数です。n
から1
まで可能な限りすべてをテストしているので1000
、実行中の製品を追跡し、ループごとにP
更新することで、階乗の実装を回避するのは簡単P*=n
です。ここだ、この戦略のPython実装万人に素数を印刷するには。
または、プログラムが1000までであれば十分であるという事実は、フェルマー素数性検定という別の戦略を開きます。一部ではa
、すべての素数n
が
pow(a,n-1)%n == 1
残念ながら、一部のコンポジットn
はこのテストにも合格していa
ます。これらは、Fermat pseudoprimesと呼ばれます。しかし、a=2
とa=3
までは一緒に失敗しないn=1105
、彼らは1000までチェック素数のあなたの目的のために十分ので(1000年ではなく100だった場合にのみ使用することができるだろう、、 a=2
。)だから、我々が素数をチェックする(ungolfedコード)
pow(2,n-1)%n == 1 and pow(3,n-1)%n == 1
これも素数2と3を認識できないため、これらは特別なケースにする必要があります。
これらのアプローチはより短いですか?私はCでコーディングしていないのでわかりません。しかし、それらは、コードの一部に落ち着いて文字を書き出す前に試す必要があるアイデアです。
int
sが32ビットであるため、Cでは役に立ちません。同じことがフェルマートにも当てはまります。
fact(int n, int m) { return (n==0) ? 1 : (n*f(n-1)) % m; }
、かなり大きな値の場合でも、結果は32ビット整数をオーバーフローしませんn
。(m
は係数です)
(n*fact(n-1,m)) % m
。これは問題を浮き彫りにします。外側のループの反復ごとに異なるfact
ため、実装の再帰を回避することはできませんm
。
同様の質問に対する私の回答の別の再利用。
編集:スタンドアロンのコード部分、呼び出す関数はありません。
for(int m,n=2;n<999;m>1?m=n%m--?m:n++:printf("%d\n",m=n));
完全なプログラム:
n=2;main(m){n<999&&main(m<2?printf("%d\n",n),n:n%m?m-1:n++);}