Todos os números primos de 0 a 1000


9

É possível diminuir esse código C? Imprime todos os números 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);}

6
Apenas para antecipar alguns votos negativos de "Não queremos desafios específicos de idiomas", pedir ajuda para obter algum código é tópico e uma história diferente dos desafios.
Martin Ender

4
Precisamos preservar o algoritmo, ou apenas o resultado final?
John Dvorak

Eu começaria i a 2 para ser estritamente preciso, uma vez que este imprime 0 e 1.
histocrat

você está tentando tornar o código mais rápido ou está usando menos caracteres no código-fonte?
precisa saber é o seguinte

11
Como você está pedindo ajuda com o golfe, seria útil incluir a contagem de caracteres da sua solução atual em sua postagem (eu a considero 89).
Mark Reed

Respostas:


7

59 57 bytes

Baseado na solução @feersum, mas a verificação de primalidade pode ser ainda mais aprimorada

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

Editado com base nos comentários de Runer112


2
A verificação ligado pode ser golfed um pouco mais: d=p++%999. Caso contrário, isso parece um trabalho de golfe bastante hermético!
precisa saber é o seguinte

10

67 bytes

Em C, não há alternativa real à divisão de testes, mas certamente pode ser um pouco de golfe.

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

Requer declarações iniciais C99, que economizam 1 byte.


6

(Eu escrevi isso sem perceber as limitações de tamanho em números inteiros em C, portanto, provavelmente não é realmente útil para encurtar o código.)

Primeiro, uma palavra sobre algoritmo. Antes de jogar seu código, você deve pensar na melhor estratégia geral para obter o resultado.

Você está verificando a primalidade fazendo a divisão de teste - testando cada divisor potencial pde i. Isso é caro em caracteres, porque são necessários dois loops. Portanto, testar a primalidade sem um loop provavelmente salvará caracteres.

Uma abordagem geralmente mais curta é usar o Teorema de Wilson : o número né primo se e somente se

fact(n-1)%n == n-1

Onde facté a função fatorial. Desde que você está testando todos os possíveis na partir 1de 1000, é fácil evitar a implementação factorial, mantendo o controle do produto em execução Pe atualizá-lo por P*=napós cada loop. Aqui está uma implementação em Python dessa estratégia para imprimir números primos de até um milhão.

Como alternativa, o fato de o seu programa ter apenas até 1000 abre outra estratégia: o teste de primalidade de Fermat . Para alguns a, todo primo nsatisfaz

pow(a,n-1)%n == 1

Infelizmente, alguns compostos ntambém passam neste teste para alguns a. Estes são chamados pseudoprimes de Fermat . Mas, a=2e a=3não falhem juntos até n=1105, portanto, eles são suficientes para o seu objetivo de verificar os números primos até 1000. (Se 1000 fossem 100, você seria capaz de usar apenas a=2.) Portanto, verificamos a primalidade com (código não destruído)

pow(2,n-1)%n == 1 and pow(3,n-1)%n == 1

Isso também falha em reconhecer os números primos 2 e 3, portanto esses precisariam ser de caixa especial.

Essas abordagens são mais curtas? Não sei porque não codifico em C. Mas, são idéias que você deve tentar antes de escolher um pedaço de código para começar a identificar caracteres.


11
O teorema de Wilson não é útil em C porque ints são de 32 bits. O mesmo vale para Fermat.
precisa saber é

@feersum Oh, atire. Isso também é um problema para os fatoriais. Existe um tipo big-int?
xnor

@xnor Não embutido.
Martin Ender

11
se alguém definir fact(int n, int m) { return (n==0) ? 1 : (n*f(n-1)) % m; }, o resultado não excederá um número inteiro de 32 bits, mesmo para valores razoavelmente grandes de n. ( mé o módulo)
apnorton

@ anorton Eu acho que você quer dizer (n*fact(n-1,m)) % m. O que destaca o problema: você não pode evitar a recursão na implementação de, factporque mserá diferente para cada iteração do loop externo.
hvd 10/01

4

78 77 caracteres

(Apenas apliquei alguns truques aprendidos em outros 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);}

76 caracteres no modo C99

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 caracteres (ou 61 para um programa completo)

Outra reutilização da minha resposta a uma pergunta semelhante .
EDIT : pedaço de código independente, sem função para chamar.

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

1

67 64 bytes

Inspirado na solução da Alchymist:

int i=1,p;for(;i++<1e3;p-i||printf("%d\n",i)){p=1;while(i%++p);}
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.