0から1000までのすべての素数


9

この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);}

6
いくつかの「言語固有の課題を望まない」という反対投票を先取りするために一部のコードのゴルフを助けることを求めるのはトピックに関するものであり、課題とは別の話です。
Martin Ender

4
アルゴリズムを保持する必要がありますか、それとも最終結果のみを保持する必要がありますか?
John Dvorak

これは0と1を出力するので、厳密に正確になるように2から始めます
。–ヒストクラート

コードをより高速に実行しようとしていますか、それともソースコードで使用する文字を少なくしようとしていますか?
user3629249 2015年

1
あなたはゴルフの支援を求めているので、現在のソリューションの文字数を投稿に含めると役立ちます(私は89とします)。
Mark Reed

回答:


7

59 57バイト

@feersumソリューションに基づくが、素数性チェックをさらに進めることができる

for(int p=1,d;d=p++%999;d||printf("%d\n",p))for(;p%d--;);

Runer112のコメントに基づいて編集


2
バインドされたチェックはもう少しゴルフすることができます:d=p++%999。そうでなければ、これはかなり気密なゴルフの仕事に見えます!
Runer112 2015年

10

67バイト

Cでは、裁判の分割に代わる本当の選択肢はありませんが、確かに少しゴルフをすることができます。

for(int p=1,d;p++<999;d&&printf("%d\n",p))for(d=p;--d>1;)d=p%d?d:1;

1バイトを節約するC99初期宣言が必要です。


6

(私はこれを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=2a=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でコーディングしていないのでわかりません。しかし、それらは、コードの一部に落ち着いて文字を書き出す前に試す必要があるアイデアです。


1
Wilsonの定理は、intsが32ビットであるため、Cでは役に立ちません。同じことがフェルマートにも当てはまります。
feersum

@feersumああ、シュート。これは、階乗の問題でもあります。big-int型はありますか?
XNOR

@xnor組み込みではありません。
マーティンエンダー、2015年

1
定義するとfact(int n, int m) { return (n==0) ? 1 : (n*f(n-1)) % m; }、かなり大きな値の場合でも、結果は32ビット整数をオーバーフローしませんn。(mは係数です)
apnorton 2015年

@anortonってことだよね(n*fact(n-1,m)) % m。これは問題を浮き彫りにします。外側のループの反復ごとに異なるfactため、実装の再帰を回避することはできませんm
hvd 2015年

4

78 77文字

(他の言語で学んだいくつかのトリックを適用しただけです。)

int i=0,p,c;for(;i<1e3;i++){c=0;for(p=2;p<i;)c+=i%p++<1;c||printf("%u\n",i);}

C99モードで76文字

for(int i=0,p,c;i<1e3;i++){c=0;for(p=2;p<i;)c+=i%p++<1;c||printf("%u\n",i);}

2

58文字(または完全なプログラムの場合は61文字)

同様の質問に対する私の回答の別の再利用。
編集:スタンドアロンのコード部分、呼び出す関数はありません。

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++);}

1

67 64バイト

アルキミストのソリューションに触発されました:

int i=1,p;for(;i++<1e3;p-i||printf("%d\n",i)){p=1;while(i%++p);}
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.