Esta é a minha primeira pergunta sobre código de golfe, e uma pergunta muito simples, por isso peço desculpas antecipadamente por ter quebrado as diretrizes da comunidade.
A tarefa é imprimir, em ordem crescente, todos os números primos menores que um milhão. O formato de saída deve ser um número por linha de saída.
O objetivo, como na maioria dos envios de código de golfe, é minimizar o tamanho do código. A otimização para o tempo de execução também é um bônus, mas é um objetivo secundário.
code-golf
kolmogorov-complexity
primes
Delan Azabani
fonte
fonte
10^6
é ainda menor;)1e6
:-DRespostas:
Mathematica ,
1724Apenas para comparação:
Como observado em um comentário, falhei em fornecer um número primo por linha; correção:
fonte
Prime~Array~78498
Também 17 :)Print/@
e terminar com;
para impedir a saída de uma longa lista deNull
s correções que, ao custo de 8 caracteres extras.Python 3, 46 bytes
No momento em que o loop chega ao teste
k
, ele iterativamente calculou o fatorial ao quadradoP=(k-1)!^2
. Sek
for primo, não aparecerá no produto1 * 2 * ... * (k-1)
, portanto não é um fator deP
. Mas, se for composto, todos os seus principais fatores são menores e, portanto, no produto. A quadratura só é realmente necessária para parark=4
de ser falsamente chamada de primo.Mais fortemente, segue-se do teorema de Wilson que quando
k
é primo,P%k
é igual1
. Embora apenas precisemos que seja diferente de zero aqui, é útil, em geral, queP%k
seja uma variável indicadora de sek
é primo.fonte
C, 61 caracteres
Quase exatamente o mesmo que este (a questão também é quase exatamente a mesma).
fonte
SEG-FAULT
após a impressão881
-O3
paragcc
resolver o problema !!n=2;main(m){n<1e6&&main(m<2?printf("%d\n",n),n:m-++n%m);}
MATLAB
(16)(12)Infelizmente, isso gera uma única linha:
mas isso é resolvido por uma simples transposição de matriz:
e posso recortar alguns caracteres usando notação exponencial (como sugerido nos comentários):
fonte
1e6
vez de1000000
ajuda aqui também.'
no finalBash (37 caracteres)
(60 caracteres)
no meu computador (CPU de 2,0 GHz, 2 GB de RAM) leva 14 segundos.
fonte
seq 2 1000000|factor|sed 's/[0-9]*: //g;/^.* .*$/ d'
seq 1e6|factor|awk '$0=$2*!$3'
é um pouco mais curto.c p
onde c é um link simbólico para cat ep é um arquivo de texto com números primos de até um milhão ... você pode fazê-lo com shell embutidos?seq
efactor
estãocoreutils
, por isso é legítimo.sed
também é bastante onipresente.coreutils
pode ser tratado como um built-in. Bash sem coreutils é como C ++ sem o STL.J, 21 caracteres
que pode ser reduzido para
se você souber quantos números primos existem abaixo de 1000000.
fonte
,.
vez de 1 [\\ para salvar um caractere. Remover o parêntese desnecessário, e usar notação exponencial:1e6
.,.i.&.(p:^:_1)1e6
Comecei com isso: Não é mais curto (depois de aplicar as sugestões do @Omar), mas achei o uso de sob interessante.PowerShell,
4744 bytesMuito lento, mas o mais curto que consegui.
PowerShell, 123 bytes
Isso é muito mais rápido; longe de ser o ideal, mas um bom compromisso entre eficiência e brevidade.
fonte
Ruby 34
fonte
Bash, 30 bytes
Como saeedn não vai agir de acordo com minha sugestão - que é mais curta e mais rápida que a abordagem dele -, pensei em postar minha própria resposta:
Como funciona
lista todos os números inteiros positivos até 1.000.000.
fatores-los um por um. Para os dez primeiros, a saída é a seguinte:
Finalmente,
altera a linha inteira (
$0
) para o produto do segundo campo (o primeiro fator primo) e a negação lógica do terceiro campo (1
se for um fator primo ou menos,0
caso contrário).Isso substitui as linhas correspondentes aos números primos pelo próprio número e todas as outras linhas pelos zeros. Como o awk imprime apenas valores reais, apenas o número principal será impresso.
fonte
awk '$0=$2*!$3'
é legal demais!Ruby
5041fonte
.to_a
, pois o Enumerable já incluiselect
. Você também pode usar a notação abreviada do Symbol # to_proc para abreviá-lo ainda mais:p (2..1e6).select &:prime?
(1 não é primo)require'prime';p Prime.take 78498
.Bash, 37
Golf mais, se eu puder ...
A maior parte disso está tentando analisar
factor
o formato de saída estranho.Leva 5,7 ou mais segundos para concluir na minha máquina.
(Aconteceu que o meu post foi o primeiro a ir para a segunda página de respostas, então ninguém vai vê-lo ...)
Solução antiga
Isso é mais longo e mais lento (leva 10 segundos).
fonte
factor
antes, mas aí está o coreutils!seq 1e6|factor|grep -oP "(?<=: )\d+$"
com um lookbehind perl-grep-P
permite regexes no estilo perl.(?<=: )
é um olhar positivo para a cadeia ":". Basicamente, isso diz que ":" deve vir antes do que corresponde\d+$
, mas na verdade não faz parte da correspondência; portanto, a-o
opção nos fornece um número correspondente após os dois pontos, ou seja, apenas fornece números onde há apenas um fator, ou seja, primo.Python 3.x: 66 caracteres
Solução mais eficiente: 87 caracteres
Baseado na peneira de Eratóstenes.
fonte
0
e1
. Você pode corrigir isso usandorange(2,10**6)
. Além disso, acho que aif
declaração deve estar em uma linha separada da saídafor
ou você recebe um erro.Haskell, 51
fonte
mapM_
paramapM
, o valor de retorno não será impresso e este é o Code Golf. ;)APL, 15
Meu intérprete teve problemas de memória, mas funciona em teoria.
fonte
⍪
na frente para fazer um número por linha e não precisa do,
.⍳
são os primeiros números inteiros.1↓
derruba o primeiro.p←
atribui a p.p∘.×p
faz uma tabuada de multiplicação.p~
remove de p o que estiver à direita. (,
Não é necessária, ela Ravels a tabela para uma lista.)Perl, 49 bytes
Expressão regular kung fu :)
Versão não destruída:
Nem sequer fez 10% de progresso enquanto digito este post!
Fonte do regex: http://montreal.pm.org/tech/neil_kandalgaonkar.shtml
fonte
1000000
pode ser escrito10**6
Julia, 11
Parece que os ins internos estão recebendo votos positivos, e eu precisava de mais palavras para obter respostas mais longas.
fonte
J (15 ou 9)
Eu não posso acreditar nessa batida do Mathematica (mesmo que seja apenas
umpor 2 caracteres)Ou:
fonte
... The output format should be one number per line of output.
É por isso que minha resposta começa com1[\
.gs2, 5 bytes
Codificado no CP437:
1C 29
empurra um milhão,11 6C
é primos abaixo,54
é mostra linhas.fonte
GolfScript, 22/20 (20/19) bytes
À custa da velocidade, o código pode ser reduzido em dois bytes:
Se o formato de saída especificado na pergunta editada for desconsiderado (que é o que muitas das respostas existentes fazem), dois bytes podem ser salvos na versão rápida e um na versão lenta:
Isso imprimirá um LF adicional após os primos da versão rápida e os primos como uma matriz do lento.
Como funciona
Ambas as versões são implementações da peneira de Eratóstenes .
A versão rápida faz o seguinte:
Conjunto
A = [ 2 3 4 … 999,999 ]
e| = [ 0 1 2 … 999,999 ]
.Conjunto
N = A[0]
e imprimirN
.Colete todos os N-ésimos elementos de
|
dentroC
. Estes são os múltiplos deN
.Set
A = A - C
.Se
A
não estiver vazio, volte para 2.A versão lenta funciona de maneira semelhante, mas, em vez de remover sucessivamente múltiplos do mínimo de "A" (que é sempre primo), remove múltiplos de todos os números inteiros positivos abaixo de 1.000.000.
Competitividade
Na ausência de funções matemáticas embutidas para fatorar ou verificar a primalidade, todas as soluções GolfScript serão muito grandes ou muito ineficientes.
Embora ainda esteja longe de ser eficiente, acho que atingi uma proporção decente de velocidade / tamanho. No momento da submissão, essa abordagem parece ser a mais curta entre as que não usam nenhum dos embutidos mencionados acima. Eu digo parece que não tenho ideia de como algumas das respostas funcionam ...
Comparei todas as quatro soluções GolfScript enviadas: w0lf (divisão de teste), minha outra resposta (teorema de Wilson) e as duas respostas. Estes foram os resultados:
fonte
NARS2000 APL, 7 caracteres
fonte
Golfscript
26 2524Editar (salvou mais um caractere graças a Peter Taylor):
Código antigo:
Este código tem apenas valor teórico, pois é incrivelmente lento e ineficiente. Eu acho que pode levar horas para correr.
Se você deseja testá-lo, tente, por exemplo, apenas os números primos de até 100:
fonte
\;
por*
. (Você também pode obter muito mais rápido para a contagem de caracteres atual por encontrar o primeiro divisor ao invés de todos eles:10 6?,2>{.),2>{1$\%!}?=},`
.,
por:x,
e\.@
porx\
(espaço em branco é devido a problemas de escape com MD nos comentários) e remova*
.CJam - 11
1e6,
- matriz de 0 ... 999999{mp},
- selecione números primosN*
- junte-se a novas linhasfonte
GolfScript, 25 (24) bytes
Se o formato de saída especificado na pergunta editada for desconsiderado, um byte poderá ser salvo:
Isso imprimirá os números primos como uma matriz (como muitas outras soluções) em vez de uma por linha.
Como funciona
A idéia geral é usar o teorema de Wilson , que afirma que n > 1 é primo se e somente se
Benchmarks
Mais rápido que a divisão experimental, mas mais lento que a peneira de Eratóstenes. Veja minha outra resposta .
fonte
Java, 110 bytes
Usando a divisão unária através do regex como um teste de primalidade.
fonte
C,
9188858281807672 caracteresO algoritmo é terrivelmente ineficiente, mas, como estamos praticando golfe de código, isso não deve importar.
fonte
main(i,j,b){for(;i++<1e6;b++&&printf("%d\n",i))for(j=2;j<i;)b=i%j++&&b;}
ou alguma idéia como essa (já que eu realmente não a compilei)i
certo ser 0? Eu acho que, se você fornecer algum argumento, ele falhará. Além disso, acho quej
haverá algum tipo de erro de tipo. Não tenho certezab
.Mathematica 25
Supondo que você não saiba o número de primos menor que 10 ^ 6:
fonte
J, 16 caracteres
Sem o requisito de formato de saída, isso pode ser reduzido para 13 caracteres:
1]\
apenas pega a matriz de primos de classificação 1, transforma-a em uma matriz de classificação 2 e coloca cada primo em sua própria linha - e, assim, o formato de saída padrão do intérprete transforma a lista de uma linha em um primo por linha.(#~ f) y
é basicamentefilter
, ondef
retorna um booleano para cada elemento emy
.i.1e6
é o intervalo de números inteiros [0,1000000) e1&p:
é uma função booleana que retorna 1 para números primos.fonte
R,
4543 caracteresPara cada número x de 2 a 1e6, basta imprimi-lo se o número de x mod 2 a x iguais a 0 for menor que 2.
fonte
Bash (433643)
Minha tentativa (não tão inteligente) foi usar o fator para fatorar o produto.
Infelizmente, com grandes números, o produto é obviamente enorme. Também levou mais de 12 horas para ser executado. Decidi publicá-lo porque achei que era único.
Aqui está o código completo.
Se fosse primos com menos de seis anos, seria razoável.
Oh, bem, eu tentei.
fonte
factor
desempenho muito pior do que o algoritmo básico da divisão de teste.C #, 70
Você não verá muito aqui por muito tempo ...
fonte
double
1e6
para umint
, masint
é exigido porRange
. (2) O interiorRange
deve levar no máximon-2
termos, caso contrário você testará on % n
que é claramente0
. (3) Você escrevex%n
quando quisern%x
. Corrigindo esses problemas, algo como isso funcionará:Enumerable.Range(2,999999).Where(n=>Enumerable.Range(2,n-2).All(x=>n%x!=0))
No entanto, isso ainda não gera os números; o requisito era um por linha.