Ist es möglich, diesen C-Code zu verkleinern? Es werden alle Primzahlen von 0 bis 1000 ausgedruckt.
C 89 Zeichen
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);}
Ist es möglich, diesen C-Code zu verkleinern? Es werden alle Primzahlen von 0 bis 1000 ausgedruckt.
C 89 Zeichen
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);}
Antworten:
59 57 Bytes
Basierend auf der @ feersum-Lösung kann die Primalitätsprüfung jedoch weiter ausgeführt werden
for(int p=1,d;d=p++%999;d||printf("%d\n",p))for(;p%d--;);
Bearbeitet basierend auf den Kommentaren von Runer112
d=p++%999
. Ansonsten sieht das ziemlich luftdicht aus!
(Ich habe dies geschrieben, ohne die Größenbeschränkungen für Ganzzahlen in C zu berücksichtigen, daher ist es wahrscheinlich nicht wirklich nützlich, um den Code zu verkürzen.)
Zunächst ein Wort zum Algorithmus. Bevor Sie Ihren Code spielen, sollten Sie über die beste Gesamtstrategie nachdenken, um das Ergebnis zu erzielen.
Sie überprüfen die Primalität, indem Sie eine Testteilung durchführen - indem Sie jeden potenziellen Teiler p
von testen i
. Das ist in Zeichen teuer, weil es zwei Schleifen braucht. Wenn Sie also die Primalität ohne Schleife testen, werden wahrscheinlich Zeichen gespeichert.
Ein oft kürzerer Ansatz ist die Verwendung von Wilsons Theorem : Die Zahl n
ist genau dann eine Primzahl, wenn
fact(n-1)%n == n-1
Wo fact
ist die Fakultätsfunktion? Da Sie alles Mögliche n
von 1
bis testen 1000
, können Sie die Implementierung von Fakultäten leicht vermeiden, indem Sie das laufende Produkt verfolgen P
und es P*=n
nach jeder Schleife aktualisieren . Hier ist eine Python-Implementierung dieser Strategie zum Drucken von Primzahlen bis zu einer Million.
Alternativ eröffnet die Tatsache, dass Ihr Programm nur bis zu 1000 sein muss, eine andere Strategie: den Fermat-Primalitätstest . Für einige a
ist jede Primzahl n
zufriedenstellend
pow(a,n-1)%n == 1
Leider bestehen einige Verbundwerkstoffe n
diesen Test auch für einige a
. Diese werden Fermat-Pseudoprimes genannt . Aber, a=2
und a=3
scheitern Sie erst zusammen n=1105
, damit sie ausreichen, um Primzahlen bis 1000 zu überprüfen. (Wenn 1000 statt 100 wären, könnten Sie nur verwenden a=2
.) Also überprüfen wir die Primalität mit (ungolfed code)
pow(2,n-1)%n == 1 and pow(3,n-1)%n == 1
Dies erkennt auch die Primzahlen 2 und 3 nicht, so dass diese in speziellen Fällen angeordnet werden müssten.
Sind diese Ansätze kürzer? Ich weiß es nicht, weil ich in C nicht codiere. Aber es sind Ideen, die Sie ausprobieren sollten, bevor Sie sich für einen Code entscheiden, um Zeichen zu finden.
int
s 32-Bit sind. Gleiches gilt für Fermat's.
fact(int n, int m) { return (n==0) ? 1 : (n*f(n-1)) % m; }
wird das Ergebnis eine 32-Bit-Ganzzahl auch für ziemlich große Werte von nicht überlaufen n
. ( m
ist der Modul)
(n*fact(n-1,m)) % m
. Was das Problem hervorhebt: Sie können die Rekursion bei der Implementierung von fact
weil nicht vermeiden, da m
sie für jede Iteration der äußeren Schleife unterschiedlich ist.
(Habe gerade einige Tricks angewendet, die in anderen Sprachen gelernt wurden.)
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);}
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);}
Eine weitere Wiederverwendung meiner Antwort auf eine ähnliche Frage .
BEARBEITEN : eigenständiges Codeteil, keine aufzurufende Funktion.
for(int m,n=2;n<999;m>1?m=n%m--?m:n++:printf("%d\n",m=n));
Komplettes Programm:
n=2;main(m){n<999&&main(m<2?printf("%d\n",n),n:n%m?m-1:n++);}
Inspiriert von Alchymists Lösung:
int i=1,p;for(;i++<1e3;p-i||printf("%d\n",i)){p=1;while(i%++p);}