Esta é a conjectura de Collatz (OEIS A006577 ):
- Comece com um número inteiro n > 1.
- Repita as seguintes etapas:
- Se n for par, divida-o por 2.
- Se n for ímpar, multiplique por 3 e adicione 1.
Está provado que, para todos os números inteiros positivos de até 5 * 2 60 , ou cerca de 57640000000000000000000 , n se tornará 1 .
Sua tarefa é descobrir quantas iterações são necessárias (de reduzir pela metade ou triplicar mais um) para atingir 1 .
Regras:
- O menor código vence.
- Se um número <2 for inserido, ou um não inteiro, ou um número não, a saída não importará.
Casos de teste
2 -> 1
16 -> 4
5 -> 5
7 -> 16
1+
é de caixa especial como)
.C -
5047 caracteresInfelizmente, o pequeno C pobre requer uma quantidade enorme de código para E / S básica, portanto, encurtar tudo isso fez com que a interface do usuário fosse pouco intuitiva.
Compile com, por exemplo
gcc -o 1 collatz.c
. A entrada é unária com dígitos separados por espaço e você encontrará a resposta no código de saída. Um exemplo com o número 17:fonte
return~-a?
salva 1. A mudançab++
para o?
caso também deve ser salvab--
.Caracteres Perl 34 (+1)
Abusar
$\
na saída final, como de costume. Execute com a-p
opção de linha de comando, a entrada é retiradastdin
.Salvo um byte devido a Elias Van Ootegem . Especificamente, a observação de que os dois seguintes são equivalentes:
Embora tenha um byte a mais, ele salva dois bytes encurtando
$_/2
para apenas.5
.Uso da amostra:
PHP 54 bytes
A arquemesis de Javascript para o Wooden Spoon Award parece ter ficado um pouco aquém neste desafio. Porém, não há muito espaço para criatividade com esse problema. A entrada é tomada como um argumento de linha de comando.
Uso da amostra:
fonte
$_
na ternário parece um desperdício, você pode raspar um outro personagem, usando*=
como este:$\++,$_*=$_&1?3+1/$_:.5while$_>1}{
. Multiplicando por1/$_
tem o mesmo efeito que+1
, por isso$_*=3+1/$_
funciona muito bem$_*=3+1/$_
é brilhante, obrigado!Mathematica (35)
Uso:
fonte
Como normalmente faço, começarei as respostas com as minhas.
JavaScript,
4644 caracteres (executado no console)fonte
Java,
165, 156, 154.134.131.129.128, 126 (as línguas detalhadas também precisam de um pouco de amor)Tudo é feito dentro do para
Isso é um homem bonito. Graças a Pater Taylor !!!, e a idéia de usar um loop for foi roubada da ugoren
Substituí Inteiro por Curto.
fonte
i(,++y)
. Você pode salvar mais dois usando em<
vez de==
.class a{public static void main(String[]a){for(int x=new Short(a[0]),y=0;x>1;System.out.println(++y))x=x%2<1?x/2:x*3+1;}}
Alterações feitas: 1) SubstituídoShort.valueOf(...)
comnew Short(...)
a -4 bytes e 2) eu coloquei ox=x%2<1?x/2:x*3+1;
no corpo dofor
-loop para se livrar da vírgula para -1 byte .Rebmu : 28
Em um problema tão breve e matemático, o GolfScript provavelmente vencerá um pouco por cento contra o Rebmu (se não for necessário dizer, leia arquivos da Internet ou gere arquivos JPG). No entanto, acho que a maioria concordaria que a lógica do Golfscript não é tão fácil de seguir e a pilha executável total em execução é maior.
Embora o criador de Rebol, Carl Sassenrath, tenha me dito que achou Rebmu "ilegível", ele está ocupado e não tem tempo para realmente praticar a transformação de porco-latino por meio de silêncio . Isso realmente é apenas transformado em:
Observe que o espaço era necessário para obter um a: em vez de um a . Este é um "conjunto de palavras!" e o avaliador percebe esse tipo de símbolo para acionar a atribuição.
Se fosse escrito em Rebol sem abreviação (ainda que de forma desajeitada), você obteria:
Rebol, como Ruby, avalia blocos até seu último valor. O loop UNTIL é uma forma curiosa de loop que não possui condição de loop, apenas para de loop quando seu bloco é avaliado como algo que não é FALSO ou NENHUM. Portanto, no momento em que
1 ==
o resultado da atribuição de A (o argumento para rebmu) ao resultado da condicional Collatz (ou é um IF-ELSE que avalia o ramo que ele escolhe) ... o loop é interrompido.J e K são inicializados com o valor inteiro zero em Rebmu. E, como mencionado acima, a coisa toda é avaliada até o último valor. Portanto, uma referência J no final do programa significa que você obtém o número de iterações.
Uso:
fonte
Repl de Python, 48
Não estou convencido de que não exista uma expressão mais curta do que
n=3*n+1;n/=1+n%2*5;
. Provavelmente encontrei uma dúzia de expressões diferentes do mesmo tamanho ...editar: Encontrei outra solução que nunca será contestada, mas é divertida demais para não ser compartilhada.
fonte
(n//2,n*3+1)[n%2]
é mais curto.n/2
funcionaria tão bem quanto sabemos que é mesmo?APL (31)
fonte
{1=⍵:0⋄2|⍵:1+∇1+3×⍵⋄1+∇⍵÷2}
{1=⍵:0⋄1+∇⊃⍵⌽0 1+.5 3×⍵}
J, 30 caracteres
Acabou um pouco mais do que o desejado
uso:
-:`(1+3&*)`]
é um gerúndio composto por três verbos, usado em três ocasiões.-:
significa "reduzir pela metade"(1+3&*)
ou(1+3*])
codifica a etapa de multiplicação e]
(identidade) ajuda ao término.2&|+1&=
forma um índice para o gerúndio. literalmente, "o restante após a divisão por dois mais se é igual a um".#verb^:a:
itera a função até que o resultado seja estável (aqui, forçado explicitamente), enquanto coleta as etapas e as conta. Roubado de @JB .<:
diminui a contagem de etapas em um para alinhar com os requisitos da pergunta.fonte
<:
,#-:
,:`(
,&*)
,=)
,)^:
.<:
significa "decremento" ou "menor ou igual",#
significa "contagem de" ou "n vezes",-:
significa "metade" ou "epsilon-igualdade",:`(
significa por sua vez o final da referida "metade", o vínculo entre dois verbos em um gerúndio e um parêntese esquerdo (usado para agrupar).&*)
significa "ligado à multiplicação" (3 ligado à multiplicação cria o operador "vezes três") e o fim do agrupamento.=
realiza verificação de igualdade ou, no sentido unário, auto-classificação.^:
é a conjunção de poder (iteração verbal). Uma vez que um monte de verbos J terminar com dois pontos, ... :-)<:#a:2&(<*|+|6&*%~)
19 bytes (-11)Esquema Gambit,
10698 caracteres, 40 parênteses(let((f(lambda(x)(cond((= x 1) 0)((odd? x)(+ 1(f(+ 1(* 3 x)))))(else(+ 1(f(/ x 2))))))))(f(read)))
9189 caracteres com define diretamente(define(f x)(cond((= x 1)0)((odd? x)(+ 1(f(+ 1(* 3 x)))))(else(+ 1(f(/ x 2))))))(f(read))
fonte
PowerShell:
7774717061Código de golfe:
Notas:
Inicialmente, tentei pegar a entrada do usuário sem forçá-la a um número inteiro, mas isso foi interrompido de uma maneira interessante. Quaisquer entradas ímpares seriam processadas incorretamente, mas mesmo as entradas funcionariam bem. Levei um minuto para perceber o que estava acontecendo.
Ao executar a multiplicação ou adição, o PowerShell trata a entrada não digitada como uma string primeiro. Portanto,
'5'*3+1
torna-se '5551' em vez de 16. As entradas pares se comportaram bem porque o PowerShell não tem uma ação padrão para divisão contra seqüências de caracteres. Mesmo as entradas pares que progrediriam com números ímpares funcionavam bem porque, quando o PowerShell chegou a um número ímpar no loop, a variável já era forçada a um número inteiro pelas operações matemáticas.Dica do PowerShell Golfer: Para alguns cenários, como este,
switch
bateif/else
. Aqui, a diferença era de 2 caracteres.Não há verificação de erro para valores não inteiros ou números inteiros menores que dois.
Se você deseja auditar o script, coloque um
;$i
pouco antes da última chave de fechamento no script.Não sei exatamente o quão bem o PowerShell lida com números que evoluem para valores muito grandes, mas espero que a precisão seja perdida em algum momento. Infelizmente, também espero que não haja muito que possa ser feito sobre isso sem inchar seriamente o script.
Código não jogado, com comentários:
Casos de teste:
Abaixo estão alguns exemplos com a auditoria ativada. Também editei a saída para maior clareza, adicionando rótulos à entrada e contagem final e colocando espaçamento para separar os valores de Collatz.
Bits interessantes sobre os números de entrada que não são dos casos de teste da pergunta:
14
e197
são números Keith31
é um Mersenne Prime6174
é a constante de Kaprekar8008135
. E Numberphile , obviamente.fonte
switch
por$i=(($i/2),($i*3+1))[$i%2]
read-host
para número - basta alterar$i*3
para3*$i
.$i*3
- por que eu não pensei nisso já?param($i)for(;$i-ne1;$x++){$i=(($i/2),(3*$i+1))[$i%2]}$x
- troque o host de leitura por um parâmetro, para obter 56 bytes . Link Try It Online80386 montagem, 16 bytes
Este exemplo usa a sintaxe da AT&T e a convenção de chamada de chamada rápida, o argumento entra em
ecx
:Aqui estão os 16 bytes resultantes do código da máquina:
fonte
Braquilog , 16 bytes
Experimente online!
Explicação
Uma solução alternativa na mesma contagem de bytes:
Experimente online!
fonte
GolfScript (23 caracteres)
Teste online
fonte
F # - 65 caracteres
fonte
Python
68585452 caracteresf=lambda n:1+(n-2and f((n/2,3*n+1)[n%2]));f(input())
Obrigado a Bakuriu e boothby pelas dicas :)
fonte
n%2and 3*n+1or n/2
para salvar 5 caracteres. Também em python2, você pode remover a chamada paraint
, reduzindo o tamanho para 58 bytes.[n/2,3*n+1][n%2]
.unsupported operand type(s) for -: 'str' and 'int'
Retina , 43 bytes
Recebe e imprime a saída em unário.
Cada linha deve ir para seu próprio arquivo. 1 byte por arquivo extra adicionado à contagem de bytes.
Você pode executar o código como um arquivo com o
-s
sinalizador Por exemplo:O algoritmo é um loop de executar uma etapa Collatz com o número unário e adicionar um novo marcador de etapa
x
no final da string, se o número não for 1.Quando o loop termina
1
, convertemos os marcadores em um número unário (removendo o primeiro1
) que é a saída desejada.fonte
Gelatina , não concorrente
12 bytes Esta resposta não é competitiva, pois o desafio antecede a criação do Jelly.
Experimente online!
Como funciona
fonte
dc, 27 caracteres
Aplicando a magia negra de boothby :
Não tenho muita certeza se entendo como - ou isso - funciona.
Uso:dc, 36 caracteres
Minha própria criação; uma abordagem um pouco mais tradicional, mesmo que eu tenha que lidar bastante com o idioma para superar a falta de uma
else
parte dasif
declarações:Internamente, ele produz todos os números da sequência e os armazena na pilha, depois abre a final
1
e exibe a altura da pilha.fonte
2<x
e se livrar dak
. Apenas no caso de você querer um byte de volta depois de quatro anos. : Dbrainfuck ,
5956 bytesExperimente online! (Ligeiramente modificado para facilitar o uso)
Entrada e saída como códigos de caracteres. Isso é mais útil com células de tamanho arbitrário, mas ainda pode funcionar com valores pequenos em tamanhos limitados de célula.
Como funciona
fonte
Hexagonia ,
4844 bytesExperimente online!
Expandido:
Note que isso falha1
por uhh ... razões . Honestamente, não tenho mais certeza de como isso funciona. Tudo o que sei é que o código para números ímpares é executado ao contrário para números pares? De alguma forma?A nova versão é muito mais limpa que a anterior, mas possui mais algumas direções em comparação e também termina em um erro de divisão por zero. O único caso em que não ocorre erro é quando ele realmente lida
1
corretamente.fonte
If a number < 2 is input ... output does not matter.
: o)C,
7069 caracteresMuito simples, sem truques.
Lê a entrada de stdin.
fonte
Q, 46
fonte
(#)1_(1<){(1+3*x;x%2)0=x mod 2}\
Ruby 1.9, 49 caracteres
Rubyfied resposta Python de Valentin CLEMENT , usando a sintaxe lambda stabby. Sqeezed-lo em uma declaração para ilegibilidade adicional.
Algumas sobrecargas porque Ruby, ao contrário do Python, não está feliz em misturar números com booleanos.
fonte
C ++ (
5148)Esta é uma função recursiva que faz isso; a leitura de entrada vem separadamente.
Tenho certeza de que posso fazer algum tipo de truque "e / ou" com as
== 0
coisas, mas não tenho idéia de como.fonte
==0
e trocar os lados do condicional.n==1
porque eu especificado na pergunta que o número é sempre maior do que 1n==1
é o caso de recursão base. Colocarn==2
lá não melhoraria a pontuação.return~-n?
e trocar os lados condicionaisn==1
==n<2
.~ - ~! (Sem comentários) -
7153Obviamente, essa linguagem não é a melhor para o golfe, pois falta uma grande quantidade de funcionalidades nativas, mas essa é a beleza dela.
Primeiro, defina
'''
como sua entrada. A função''
pode ser chamada com%
a entrada e retornará a resposta, da seguinte maneira:'''=~~~~~:''&%:
Isso retornará
~~~~~
. Na verdade, ele funciona paran==1
(faz um loop para sempren==0
).Como sempre com esse idioma, não testado.
fonte
JavaScript (ES6) - 29 caracteres
Cria uma função
f
que aceita um único argumento e retorna o número de iterações.JavaScript - 31 caracteres
Assume que a entrada está na variável
n
e cria uma variávelc
que contém o número de iterações (e também será exibidac
no console como o último comando).fonte
Perl 6, 40 bytes
Método da função recursiva, conforme Valentin CLEMENT e daniero : 40 caracteres
Método da lista preguiçosa: 32 caracteres
fonte
> <>,
27 2623 bytesComo as outras respostas, <<>, isso cria a sequência na pilha. Quando a sequência atinge 2, o tamanho da pilha é o número de etapas executadas.
Graças a @Hohmannfan, economizamos 3 bytes por um método muito inteligente de calcular diretamente o próximo valor. A fórmula usada para calcular o próximo valor na sequência é:
A fração mapeia números pares para 0,5 e números ímpares para 3. Multiplicando
n
e adicionandon%2
conclui o cálculo - não é necessário escolher o próximo valor!Edit 2: Aqui está a versão pré- @ Hohmannfan:
O truque aqui é que ambos
3n+1
en/2
são computados em cada etapa da sequência, e aquele a ser descartado da sequência é escolhido posteriormente. Isso significa que o código não precisa ramificar até que 1 seja alcançado e o cálculo da sequência pode residir em uma linha de código.Edit: Golpeou outro caractere depois de perceber que o único número inteiro positivo que pode levar a 1 é 2. Como a saída do programa não importa para a entrada <2, a geração da sequência pode terminar quando 2 for atingido, deixando o tamanho da pilha sendo o número exato de etapas necessárias.
Versão anterior:
fonte
\::2%:@5*1+2,*+:2=?