A conjectura inversa de Collatz

13

Eu acho que a Conjectura Collatz já é bem conhecida. Mas e se invertermos as regras?

Comece com um número inteiro n> = 1.

Repita as seguintes etapas:

Se n for par , multiplique por 3 e adicione 1.

Se n for ímpar , subtraia 1 e divida por 2.

Pare quando atingir 0

Imprima os números iterados.

Casos de teste:

 1        => 1, 0
 2        => 2, 7, 3, 1, 0
 3        => 3, 1, 0
10        => 10, 31, 15, 7, 3...
14        => 14, 43, 21, 10, ...

Regras:

  • Essa sequência não funciona para muitos números porque entra em um loop infinito. Você não precisa lidar com esses casos. Apenas imprimir os casos de teste acima é suficiente.

  • Sugeri subtrair 1 e dividir por dois para fornecer um número inteiro válido para continuar, mas não é necessário que seja calculado dessa maneira. Você pode dividir por 2 e converter para número inteiro ou quaisquer outros métodos que fornecerão a saída esperada.

  • Você também precisa imprimir a entrada inicial.

  • A saída não precisa ser formatada como os casos de teste. foi só uma sugestão. No entanto, a ordem iterada deve ser respeitada.

  • O menor código vence.

Eduardo Hoefel
fonte
9
Como essa é sua terceira pergunta em poucas horas, recomendo que você verifique o Sandbox , o local onde geralmente postamos rascunhos de perguntas para obter feedback e para garantir que não sejam duplicados.
caird coinheringaahing
Obrigado @cairdcoinheringaahing. Eu não sabia sobre esta página.
Eduardo Hoefel 4/11
Temos que imprimir 0no final?
flawr
2
Você pode querer expandir os dois últimos casos de teste, uma vez que eles não são tão longa
Jo rei
3
@JoKing Eu o comprimi porque repete a saída das outras linhas. No ponto em que você alcança 3 , ele tem a mesma saída de quando você inicia a partir dele. O mesmo se aplica a 10 ou qualquer outro número.
Eduardo Hoefel

Respostas:

5

Perl 6 , 30 bytes

{$_,{$_%2??$_+>1!!$_*3+1}...0}

Experimente online!

Bloco de código anônimo que retorna uma sequência.

Explicação:

{$_,{$_%2??$_+>1!!$_*3+1}...0}
{                            }   # Anonymous code block
   ,                     ...     # Define a sequence
 $_                              # That starts with the given value
    {                   }        # With each element being
     $_%2??     !!               # Is the previous element odd?
           $_+>1                 # Return the previous element bitshifted right by 1
                  $_*3+1         # Else the previous element multiplied by 3 plus 1
                            0    # Until the element is 0
Brincadeira
fonte
2

Python 2, 54 52 44 bytes

n=input()
while n:print n;n=(n*3+1,n/2)[n%2]

-2 bytes graças ao Sr. Xcoder

Certamente deve haver uma maneira mais rápida. Estranhamente, quando experimentei um lambda, era o mesmo número anterior. Provavelmente estou tendo alucinações.

Experimente online!

Quintec
fonte
-2 bytes
Sr. Xcoder 04/11
@ Mr.Xcoder Ah, obrigado.
Quintec 04/11
1
50 bytes
Jo King
Embora o 0agora seja opcional, é mais curto se livrar do segundoprint
Jo King
Na verdade, agora você pode fazer isso em 44
Sr. Xcoder 5/11
2

Haskell , 76 69 61 56 bytes

Eu sinto que isso é muito longo. Aquil produz uma lista infinita da sequência inversa-colatz, e a função anônima na primeira linha apenas a corta no lugar certo.

Obrigado por -5 bytes @ ØrjanJohansen!

fst.span(>0).l
l r=r:[last$3*k+1:[div k 2|odd k]|k<-l r]

Experimente online!

flawr
fonte
Não há números negativos, portanto (>0)deve ser suficiente. Também há uma oddfunção.
Ørjan Johansen
@ ØrjanJohansen Muito obrigado!
flawr
2

05AB1E , 15 14 bytes

[Ð=_#Èi3*>ë<2÷

-1 byte graças a @MagicOctopusUrn .

Experimente online.

Explicação:

[             # Start an infinite loop
 Ð            #  Duplicate the top value on the stack three times
              #  (Which will be the (implicit) input in the first iteration)
  =           #  Output it with trailing newline (without popping the value)
   _#         #  If it's exactly 0: stop the infinite loop
     Èi       #  If it's even:
       3*     #   Multiply by 3
         >    #   And add 1
      ë       #  Else:
       <      #   Subtract 1
        2÷    #   And integer-divide by 2
Kevin Cruijssen
fonte
[Ð=_#Èi3*>ë<2÷com em =vez de D,.
Magic Octopus Urn
@MagicOctopusUrn Ah, isso foi muito ruim de esquecer .. Obrigado! :)
Kevin Cruijssen 7/11
2

JAEL , 18 bytes

![ؼw>î?èÛ|õÀ

Experimente online!

Eduardo Hoefel
fonte
1
Seu link permanente parece não estar funcionando. O programa apenas imprime a entrada e pára.
Dennis
Sim, você está certo. Vou pedir "eles" para puxar a versão mais recente: P
Eduardo Hoefel 09/11/19
Adicionei JAEL à lista de idiomas para golfe . Entre em contato se tiver alguma informação errada :-)
917 ETHproductions
@ETHproductions Muito obrigado: Eu acho que posso dizer que a especialidade é o pacote de utilitários que ajuda o programador a compactar o código, mas sou apenas eu que estou tentando comercializá-lo.
Eduardo Hoefel 12/11/19
1

JavaScript (ES6), 31 bytes

f=n=>n&&n+' '+f(n&1?n>>1:n*3+1)

Experimente online!

Ou 30 bytes na ordem inversa.

Arnauld
fonte
1

Wolfram Language (Mathematica) , 35 bytes

0<Echo@#&&#0[3#+1-(5#+3)/2#~Mod~2]&

Experimente online!

0<Echo@# && ...&é uma avaliação de curto-circuito: imprime a entrada #, verifica se é positiva e, em caso afirmativo, avalia .... Nesse caso, ...é #0[3#+1-(5#+3)/2#~Mod~2]; como #0(o slot zeroth) é a própria função, é uma chamada recursiva 3#+1-(5#+3)/2#~Mod~2, que simplifica 3#+1quando #é par e (#-1)/2quando #é ímpar.

Misha Lavrov
fonte
1

PowerShell, 53 52 bytes

param($i)for(;$i){$i;$i=(($i*3+1),($i-shr1))[$i%2]}0

Experimente Online!

Edit:
-1 byte graças a @mazzy

J. Bergmann
fonte
você pode tentar em for(;$i)vez dissowhile($i)
mazzy 5/11
1

Emojicode 0.5 , 141 bytes

🐖🎅🏿🍇🍮a🐕😀🔡a 10🔁▶️a 0🍇🍊😛🚮a 2 1🍇🍮a➗a 2🍉🍓🍇🍮a➕✖️a 3 1🍉😀🔡a 10🍉🍉

Experimente online!

🐖🎅🏿🍇
🍮a🐕      👴 input integer variable 'a'
😀🔡a 10      👴 print input int
🔁▶️a 0🍇      👴 loop while number isn’t 0
🍊😛🚮a 2 1🍇     👴 if number is odd
🍮a➗a 2       👴 divide number by 2
🍉
🍓🍇      👴 else
🍮a➕✖️a 3 1   👴 multiply by 3 and add 1
🍉
😀🔡a 10     👴 print iteration
🍉🍉
X1M4L
fonte
1

MathGolf , 12 bytes

{o_¥¿½É3*)}∟

Experimente online!

Explicação

{             Start block of arbitrary length
 o            Output the number
  _           Duplicate
   ¥          Modulo 2
    ¿         If-else with the next two blocks. Implicit blocks consist of 1 operator
     ½        Halve the number to integer (effectively subtracting 1 before)
      É       Start block of 3 bytes
       3*)    Multiply by 3 and add 1
          }∟  End block and make it do-while-true
maxb
fonte
Eu adicionei MathGolf à lista de golfe langs --feel livre para me corrigir se eu tenho alguma coisa errada :-)
ETHproductions
Obrigado por adicioná-lo! Tudo parece certo para mim.
maxb
1

código de máquina x86, 39 bytes

00000000: 9150 6800 0000 00e8 fcff ffff 5958 a901  .Ph.........YX..
00000010: 0000 0074 04d1 e8eb 066a 035a f7e2 4009  ...t.....j.Z..@.
00000020: c075 dec3 2564 20                        .u..%d 

Assembly (sintaxe NASM):

section .text
	global func
	extern printf
func:					;the function uses fastcall conventions
	xchg eax, ecx			;load function arg into eax
	loop:
		push eax
		push fmt
		call printf	;print eax
		pop ecx
		pop eax
		test eax, 1	;if even zf=1
		jz even		;if eax is even jmp to even
		odd:		;eax=eax/2
			shr eax, 1
			jmp skip
		even:		;eax=eax*3+1
			push 3
			pop edx
			mul edx
			inc eax
		skip:
		or eax, eax
		jne loop	;if eax!=0, keep looping
	ret			;return eax
section .data
	fmt db '%d '

Experimente online!

Logern
fonte
1

R , 66 bytes 61

-5 bytes graças a Robert S. na consolidação de ifelse ife na remoção de colchetes, e x! = 0 a x> 0

print(x<-scan());while(x>0)print(x<-`if`(x%%2,(x-1)/2,x*3+1))

ao invés de

print(x<-scan());while(x!=0){print(x<-ifelse(x%%2,(x-1)/2,x*3+1))}

Experimente online!

Sumner18
fonte
1
61 bytes
Robert S.
0

perl -Minteger -nlE, 39 bytes

{say;$_=$_%2?$_/2:3*$_+1 and redo}say 0

fonte
0

Adicionar ++ , 38 35 33 bytes

D,f,@:,d3*1+$2/iA2%D
+?
O
Wx,$f>x

Experimente online!

Como funciona

Primeiro, começamos definindo uma função f(x), que usa um único argumento, executa a operação Collatz invertida em xentão gera o resultado. Isso é,

f(x)={xé par,3x+1xé estranho,x2

Quando no modo de função, o Add ++ usa um modelo de memória de pilha, caso contrário, as variáveis ​​são usadas. Ao calcularf(x), a pilha parece inicialmente S=[x].

Duplicamos esse valor ( d) para gerarS=[x,x]. Em seguida, produzimos a primeira opção possível,3x+1( 3*1+), troque os dois principais valores e calculex2, deixando S=[3x+1,x2].

Em seguida, empurramos x para Se calcule o bit de x ie x%2, Onde uma%bdenota o restante ao dividiruma por b. Isso nos deixa comS=[3x+1,x2,(x%2)]. Por fim, usamos Dpara selecionar o elemento no índice especificado por(x%2). Se isso é0 0, retornamos o primeiro elemento, ou seja, 3x+1, caso contrário, retornamos o segundo elemento, x2.

Isso completa a definição de f(x)no entanto, ainda não o colocamos em prática. As próximas três linhas mudaram do modo de função para o modo baunilha, onde operamos em variáveis. Para ser mais preciso, neste programa, operamos apenas uma variável, a variável ativa , representada pela letra x. No entanto, xpode ser omitido dos comandos em que obviamente é o outro argumento.

Por exemplo, +?é idêntico x+?ae atribui a entrada a x, mas como xé a variável ativa , ela pode ser omitida. Em seguida, produzimos x, em seguida, inteiro o loop while, que faz um loop pelo tempo quex0 0. O circuito é muito simples, consistindo em uma única instrução: $f>x. Tudo isso faz é executadof(x), em seguida, atribua isso a x, atualizando xa cada iteração do loop.

caird coinheringaahing
fonte
Apenas para entender: a quebra de linha faz parte do código? Ou é apenas para uma melhor explicação? Eu realmente não conheço esse idioma.
Eduardo Hoefel 4/11
@EduardoHoefel Break line?
caird coinheringaahing
@cairdcoinheringaahing Os personagens da nova linha, presumivelmente.
Lynn
0

Retina 0.8.2 , 46 bytes

.+
$*
{*M`1
^(..)+$
$&$&$&$&$&$&111
1(.*)\1
$1

Experimente online! Explicação:

.+
$*

Converta para unário.

{

Repita até que o valor pare de mudar.

*M`1

Imprima o valor em decimal.

^(..)+$
$&$&$&$&$&$&111

Se for par, multiplique por 6 e adicione 3.

1(.*)\1
$1

Subtraia 1 e divida por 2.

A nova linha à direita pode ser suprimida adicionando um ;antes de {.

Neil
fonte
0

Raquete , 75 bytes

(define(f n)(cons n(if(= n 0)'()(if(odd? n)(f(/(- n 1)2))(f(+(* 3 n)1))))))

Experimente online!

Equivalente à solução Common Lisp da JRowan.

Galen Ivanov
fonte
0

C # (.NET Core) , 62 bytes

a=>{for(;a>0;a=a%2<1?a*3+1:a/2)Console.Write(a+" ");return a;}

Experimente online!

Ungolfed:

a => {
    for(; a > 0;                // until a equals 0
        a = a % 2 < 1 ?             // set a depending on if a is odd or even
                a * 3 + 1 :             // even
                a / 2                   // odd (minus one unnecessary because of int casting)
    )
        Console.Write(a + " "); // writes the current a to the console
    return a;                   // writes a to the console (always 0)
}
Meerkat
fonte