¿Es posible hacer este código C más pequeño? Imprime todos los primos de 0 a 1000.
C, 89 caracteres
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);}
¿Es posible hacer este código C más pequeño? Imprime todos los primos de 0 a 1000.
C, 89 caracteres
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);}
Respuestas:
59 57 bytes
Basado en la solución @feersum, pero el control de primalidad puede ser más avanzado
for(int p=1,d;d=p++%999;d||printf("%d\n",p))for(;p%d--;);
Editado en base a los comentarios de Runer112
d=p++%999. De lo contrario, ¡esto parece un trabajo de golf bastante hermético!
(Escribí esto sin darme cuenta de las limitaciones de tamaño en los enteros en C, por lo que probablemente no sea realmente útil para acortar el código).
Primero, una palabra sobre algoritmo. Antes de jugar golf su código, debe pensar en la mejor estrategia general para obtener el resultado.
Estás verificando la primalidad haciendo una división de prueba, probando cada divisor potencial pde i. Eso es costoso en los personajes porque requiere dos bucles. Por lo tanto, probar la primalidad sin un bucle probablemente ahorrará caracteres.
Un enfoque a menudo más corto es usar el Teorema de Wilson : el número nes primo si y solo si
fact(n-1)%n == n-1
¿Dónde factestá la función factorial? Como está probando todo lo posible ndesde el 1principio 1000, es fácil evitar implementar factorial al realizar un seguimiento del producto en ejecución Py actualizarlo P*=ndespués de cada ciclo. Aquí hay una implementación de Python de esta estrategia para imprimir primos de hasta un millón.
Alternativamente, el hecho de que su programa solo tenga que ser hasta 1000 abre otra estrategia: la prueba de primalidad de Fermat . Para algunos a, cada primo nsatisface
pow(a,n-1)%n == 1
Desafortunadamente, algunos compuestos ntambién pasan esta prueba para algunos a. Estos se llaman pseudoprimos de Fermat . Pero, a=2y a=3no fracasen juntos hasta n=1105, por lo que son suficientes para su propósito de verificar números primos hasta 1000. (Si 1000 en lugar de 100, solo podría usarlo a=2). Entonces, verificamos la primalidad con (código no protegido)
pow(2,n-1)%n == 1 and pow(3,n-1)%n == 1
Esto tampoco reconoce los números primos 2 y 3, por lo que estos deberían estar en mayúsculas especiales.
¿Son estos enfoques más cortos? No lo sé porque no codifico en C. Pero, son ideas que debes probar antes de decidirte por un código para comenzar a escribir caracteres.
ints son de 32 bits. Lo mismo va para Fermat's.
fact(int n, int m) { return (n==0) ? 1 : (n*f(n-1)) % m; }, el resultado no desbordará un entero de 32 bits incluso para valores bastante grandes de n. ( mes el módulo)
(n*fact(n-1,m)) % m. Lo que resalta el problema: no puede evitar la recurrencia en la implementación de factporque mserá diferente para cada iteración del bucle externo.
(Solo apliqué algunos trucos aprendidos en otros idiomas).
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);}
Otra reutilización de mi respuesta a una pregunta similar .
EDITAR : pieza de código independiente, no hay función para llamar.
for(int m,n=2;n<999;m>1?m=n%m--?m:n++:printf("%d\n",m=n));
Programa completo:
n=2;main(m){n<999&&main(m<2?printf("%d\n",n),n:n%m?m-1:n++);}
Inspirado por la solución de Alchymist:
int i=1,p;for(;i++<1e3;p-i||printf("%d\n",i)){p=1;while(i%++p);}