È possibile ridurre questo codice C? Stampa tutti i numeri primi da 0 a 1000.
C, 89 caratteri
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);}
È possibile ridurre questo codice C? Stampa tutti i numeri primi da 0 a 1000.
C, 89 caratteri
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);}
Risposte:
59 57 byte
Basato sulla soluzione @feersum ma il controllo della primalità può essere ulteriormente approfondito
for(int p=1,d;d=p++%999;d||printf("%d\n",p))for(;p%d--;);
Modificato in base ai commenti di Runer112
d=p++%999. Altrimenti, questo sembra un lavoro da golf piuttosto ermetico!
(Ho scritto questo senza rendersi conto delle limitazioni di dimensione sugli interi in C, quindi probabilmente non è effettivamente utile per abbreviare il codice.)
Innanzitutto, una parola sull'algoritmo. Prima di giocare a golf con il codice, dovresti pensare alla migliore strategia generale per ottenere il risultato.
Stai verificando la primalità facendo la divisione di prova - testando ogni potenziale divisore pdi i. È costoso nei personaggi perché ci vogliono due anelli. Quindi, testare la primalità senza un loop probabilmente salverà i personaggi.
Un approccio spesso più breve è quello di usare il Teorema di Wilson : il numero nè primo se e solo se
fact(n-1)%n == n-1
dov'è factla funzione fattoriale. Dal momento che stai testando tutto il possibile nda 1a 1000, è facile evitare l'implementazione fattoriale tenendo traccia del prodotto in esecuzione Pe aggiornandolo P*=ndopo ogni ciclo. Ecco un'implementazione Python di questa strategia per stampare numeri primi fino a un milione.
In alternativa, il fatto che il tuo programma debba essere solo fino a 1000 apre un'altra strategia: il test di primalità Fermat . Per alcuni a, ogni numero primo nsoddisfa
pow(a,n-1)%n == 1
Sfortunatamente, alcuni composti nsuperano anche questo test per alcuni a. Questi sono chiamati pseudoprimi di Fermat . Ma, a=2e a=3non fallire insieme fino a quando n=1105, quindi sono sufficienti per il tuo scopo di controllare i numeri primi fino a 1000. (Se 1000 fossero invece 100, saresti in grado di usare solo a=2.) Quindi, controlliamo la primalità con (codice non golfizzato)
pow(2,n-1)%n == 1 and pow(3,n-1)%n == 1
Anche questo non riesce a riconoscere i numeri primi 2 e 3, quindi quelli dovrebbero essere sottoposti a casi speciali.
Questi approcci sono più brevi? Non lo so perché non scrivo codice in C. Ma sono idee che dovresti provare prima di accontentarti di un pezzo di codice per iniziare a eliminare i caratteri.
ints sono a 32 bit. Lo stesso vale per Fermat.
fact(int n, int m) { return (n==0) ? 1 : (n*f(n-1)) % m; }il risultato non supererà un numero intero a 32 bit per valori anche abbastanza grandi di n. ( mè il modulo)
(n*fact(n-1,m)) % m. Il che evidenzia il problema: non è possibile evitare la ricorsione nell'implementazione di factperché msarà diverso per ogni iterazione del ciclo esterno.
(Ho appena applicato alcuni trucchi appresi in altre lingue.)
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);}
Un altro riutilizzo della mia risposta a una domanda simile .
EDIT : codice autonomo, nessuna funzione da chiamare.
for(int m,n=2;n<999;m>1?m=n%m--?m:n++:printf("%d\n",m=n));
Programma completo:
n=2;main(m){n<999&&main(m<2?printf("%d\n",n),n:n%m?m-1:n++);}
Ispirato alla soluzione di Alchymist:
int i=1,p;for(;i++<1e3;p-i||printf("%d\n",i)){p=1;while(i%++p);}