Inspirado em http://xkcd.com/710/ aqui está um código de golfe para ele.
O desafio
Dado um número inteiro positivo maior que 0, imprima a sequência de pedras de granizo para esse número.
A sequência de Hailstone
Veja a Wikipedia para mais detalhes.
- Se o número for par, divida-o por dois.
- Se o número for ímpar, triplique-o e adicione um.
Repita isso com o número produzido até chegar a 1. (se continuar depois de 1, ele fará um loop infinito de 1 -> 4 -> 2 -> 1...
)
Às vezes, o código é a melhor maneira de explicar, então aqui estão alguns da Wikipedia
function collatz(n)
show n
if n > 1
if n is odd
call collatz(3n + 1)
else
call collatz(n / 2)
Este código funciona, mas estou adicionando um desafio extra. O programa não deve ser vulnerável a estouro de pilha . Portanto, ele deve usar iteração ou recursão de cauda.
Além disso, pontos de bônus se ele pode calcular grandes números e a linguagem ainda não o implementou. (ou se você reimplementar o suporte a grandes números usando inteiros de comprimento fixo)
Caso de teste
Number: 21
Results: 21 -> 64 -> 32 -> 16 -> 8 -> 4 -> 2 -> 1
Number: 3
Results: 3 -> 10 -> 5 -> 16 -> 8 -> 4 -> 2 -> 1
Além disso, o código de golfe deve incluir entrada e saída completas do usuário.
Respostas:
conjunto x86, 1337 caracteres
fonte
int 23h
.Befunge
fonte
LOLCODE: 406 CHARAKTERZ
TESTADO UNDR JUSTIN J. MEZA'S INTERPRETR . KTHXBYE!
fonte
Python -
95645146 charObviamente, não produz um estouro de pilha.
fonte
input
não faz umeval
.n=input()*2
Perl
Decidi ser um pouco anticompetitivo e mostrar como você normalmente codificaria esse problema em Perl.
Há também uma entrada de código de golfe de 46 (total) char no final.
Todos esses três primeiros exemplos começam com este cabeçalho.
Versão recursiva simples
Versão iterativa simples
Versão iterativa otimizada
Agora vou mostrar como você faria esse último exemplo com uma versão do Perl anterior à v5.10.0
Benchmark
Em primeiro lugar, o IO sempre será a parte lenta. Portanto, se você realmente os comparou como estão, deverá obter aproximadamente a mesma velocidade de cada um.
Para testá-los, abri um identificador de arquivo para
/dev/null
($null
) e editei todossay $n
para, em vez disso, lersay {$null} $n
. Isso é para reduzir a dependência de IO.Depois de executá-lo 10 vezes, aqui está uma saída de amostra representativa:
Finalmente, uma entrada real de código de golfe:
46 caracteres no total
Se você não precisa imprimir o valor inicial, pode remover mais 5 caracteres.
41 chars totalizam
31 chars para a parte do código real, mas o código não funcionará sem o
-n
switch. Portanto, incluo o exemplo completo em minha contagem.fonte
$i + 1
há sempre adição (resposta à entrada do blog). UsarSub::Call::Recur
também é uma otimização. Caso contrário, eu usaria@_=$n;goto &Collatz
. (É 10-20% mais lento se você mudarstate @next
paramy @next
Haskell, 62 chars
637683,86,97,137A entrada do usuário, a saída impressa, usa memória e pilha constantes, funciona com números inteiros arbitrariamente grandes.
Um exemplo de execução deste código, dado um número de 80 dígitos de todos os '1s (!) Como entrada, é muito divertido de olhar.
Versão original, somente função:
Haskell 51 chars
Quem o @ & ^ # precisa de condicionais, afinal?
(editar: eu estava sendo "inteligente" e usei o conserto. Sem ele, o código caiu para 54 caracteres. edit2: caiu para 51 por fatoração
f()
)fonte
c 1=[1];c n=n:(c$div(n
mod2*(5*n+2)+n)2)
- 41 caracteres, usa o fato de que este é k * (3n + 1) + (1-k) * n / 2 onde k = n mod 2Golfscript: 20 caracteres
Isso é equivalente a
fonte
21
por~
fará com que o programa use um número de stdin(eval):1:in
inicializar ': método indefinidoleftparen' for nil:NilClass (NoMethodError)
ao substituir21
por~
.echo 21 | ruby golfscript.rb collatz.gs
bc 41 chars
Acho que
bc
foi inventado para esse tipo de problema :Teste:
Código adequado:
bc
lida com números com atéINT_MAX
dígitosEdit: O artigo da Wikipedia menciona que esta conjectura foi verificada para todos os valores até 20x2 58 (aprox. 5,76e18 ). Este programa:
testa 2 20.000 +1 (aprox. 3,98e 6.020 ) em 68 segundos, 144.404 ciclos.
fonte
cat /dev/urandom | tr -dc '0-9' | head -c 10000 | bc collatz-conjecture.bc
bc
Perl: 31 caracteres
Editado para remover 2 espaços desnecessários.
Editado para remover 1 espaço desnecessário.
fonte
MS Excel, 35 caracteres
Retirado direto da Wikipedia :
Bastou copiar / colar a fórmula 111 vezes para obter o resultado de um número inicial de 1000.;)
fonte
C: 64 caracteres
Com suporte a grande número inteiro: 431 caracteres (necessários)
Nota : Não remova
#include <stdlib.h>
sem pelo menos prototipar malloc / realloc, pois isso não será seguro em plataformas de 64 bits (void * de 64 bits será convertido para int de 32 bits).Este ainda não foi testado vigorosamente. Ele poderia usar um pouco de encurtamento também.
Versões prévias:
(removeu 12 caracteres porque ninguém segue o formato de saída ...: |)
fonte
Outra versão do montador. Este não está limitado a números de 32 bits, ele pode lidar com números de até 10 65534 embora o formato ".com" que o MS-DOS usa esteja limitado a números de 80 dígitos. Escrito para o assembler A86 e requer uma caixa Win-XP DOS para funcionar. Monta até 180 bytes:
fonte
dc - 24 caracteres
2528dc
é uma boa ferramenta para esta sequência:Também 24 caracteres usando a fórmula da entrada Golfscript :
57 caracteres para atender às especificações:
fonte
Esquema: 72
Isso usa recursão, mas as chamadas são recursivas no final, então acho que serão otimizadas para iteração. Em alguns testes rápidos, não consegui encontrar um número para o qual a pilha estourou de qualquer maneira. Por exemplo:
(C 9876543219999999999000011234567898888777766665555444433332222 7777777777777777777777777777777798797657657651234143375987342987 5398709812374982529830983743297432985230985739287023987532098579 058095873098753098370938753987)
... funciona muito bem. [isso é tudo um número - eu apenas quebrei para caber na tela.]
fonte
Mathematica, 45
50charsfonte
OddQ[#]
porOddQ@#
para economizar 1 caractere.c[n_]:=NestWhileList[If[OddQ@#,3#+1,#/2]&,n,#>1&]
Ruby, 50 caracteres, sem estouro de pilha
Basicamente, uma cópia direta da solução Python de makapuf :
Ruby, 45 caracteres, irá transbordar
Basicamente, uma cópia direta do código fornecido na pergunta:
fonte
n.odd??
não fico definido. Além disso, é vulnerável a estouros de pilha com grandes números.p n=[n/2,n*3+1][n%2]
fonte
Python 45 Char
Raspou um carvão da resposta de Makapuf.
fonte
TI-BASIC
Não o mais curto, mas uma abordagem inovadora. Certamente desacelerará consideravelmente com grandes sequências, mas não deve transbordar.
fonte
Haskell: 50
fonte
c 1=[1];c n=n:(c$[n
div2,3*n+1]!!(n
mod2))
, 44 charsnão a mais curta, mas uma solução elegante de clojure
fonte
C #: 216 caracteres
em formato longo:
Nova versão, aceita um número como entrada fornecida através da linha de comando, sem validação de entrada.
173154 caracteres.em formato longo:
Eu sou capaz de raspar alguns caracteres retirando a ideia nesta resposta de usar um loop for em vez de um tempo. 150 caracteres.
fonte
Ruby, 43 caracteres
bignum suportado, com susceptibilidade de estouro de pilha:
... e 50 caracteres, bignum suportado, sem estouro de pilha:
Parabéns a Jordan. Eu não sabia sobre 'p' como um substituto para opções de venda.
fonte
nroff 1
Correr com
nroff -U hail.g
1. versão groff
fonte
groff -U hail.g
e você obterá PostScript! :-)Scala + Scalaz
E em ação:
Scala 2.8
Isso também inclui o 1 final.
Com o seguinte implícito
isso pode ser encurtado para
Editar - 58 caracteres (incluindo entrada e saída, mas não incluindo o número inicial)
Pode ser reduzido em 2 se você não precisar de novas linhas ...
fonte
F #, 90 caracteres
Ou, se você não estiver usando F # interativo para exibir o resultado, 102 caracteres:
fonte
Lisp comum, 141 caracteres:
Execução de teste:
fonte
O programa de Jerry Coffin tem overflow de inteiros, experimente este:
testado com
O número inferior a 100 milhões com o tempo total de parada mais longo é 63.728.127, com 949 passos.
O número menor que 1 bilhão com o tempo total de parada mais longo é 670.617.279, com 986 etapas.
fonte
unsigned long long
.ruby, 43, possivelmente atendendo ao requisito de E / S
Correr com
ruby -n hail
fonte
C #: 659 caracteres com suporte BigInteger
Ungolfed
fonte