La conjetura inversa de Collatz

13

Creo que la Conjetura de Collatz ya es conocida. Pero, ¿y si invertimos las reglas?

Comience con un número entero n> = 1.

Repita los siguientes pasos:

Si n es par , multiplíquelo por 3 y agregue 1.

Si n es impar , reste 1 y divídalo por 2.

Pare cuando llegue a 0

Imprime los números iterados.

Casos de prueba:

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

Reglas:

  • Esta secuencia no funciona para muchos números porque entra en un bucle infinito. No necesita manejar esos casos. Solo imprimir los casos de prueba anteriores es suficiente.

  • Sugerí restar 1 y dividir por dos para dar un número entero válido para continuar, pero no es necesario que se calcule de esa manera. Puede dividir por 2 y convertir a entero o cualquier otro método que dé el resultado esperado.

  • También debe imprimir la entrada inicial.

  • La salida no necesita formatearse como los casos de prueba. Era solo una sugerencia. Sin embargo, se debe respetar el orden iterado.

  • El código más pequeño gana.

Eduardo Hoefel
fuente
99
Como esta es su tercera pregunta en tantas horas, le recomiendo que visite el Sandbox , el lugar donde generalmente publicamos borradores de preguntas para obtener comentarios y asegurarse de que no sean duplicados.
caird coinheringaahing
Gracias @cairdcoinheringaahing. No sabía sobre esta página.
Eduardo Hoefel el
¿Tenemos que imprimir 0al final?
defecto
2
Es posible que desee ampliar los dos últimos casos de prueba, ya que no son tan largos
Jo King
3
@JoKing Lo comprimí porque repite la salida de las otras líneas. En el punto en que alcanza 3 , tiene la misma salida de cuando comienza desde allí. Lo mismo se aplica para 10 o cualquier otro número.
Eduardo Hoefel

Respuestas:

5

Perl 6 , 30 bytes

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

Pruébalo en línea!

Bloque de código anónimo que devuelve una secuencia.

Explicación:

{$_,{$_%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
Jo King
fuente
2

Python 2, 54 52 44 bytes

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

-2 bytes gracias al Sr. Xcoder

Ciertamente debe haber una forma más rápida. Curiosamente, cuando probé una lambda fue el mismo bytecount. Probablemente estoy alucinando.

Pruébalo en línea!

Quintec
fuente
-2 bytes
Sr. Xcoder
@ Mr.Xcoder Ah, gracias.
Quintec
1
50 bytes
Jo King el
Aunque 0ahora es opcional, es más corto deshacerse del segundoprint
Jo King,
De hecho, ahora puedes hacerlo en 44
Mr. Xcoder
2

Haskell , 76 69 61 56 bytes

Siento que esto es demasiado tiempo. Aquí lproduce una lista infinita de la secuencia inversa-collatz, y la función anónima en la primera línea simplemente la corta en el lugar correcto.

Gracias por -5 bytes @ ØrjanJohansen!

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

Pruébalo en línea!

falla
fuente
No hay números negativos, por lo que (>0)debería ser suficiente. También hay una oddfunción.
Ørjan Johansen
@ ØrjanJohansen ¡Muchas gracias!
falla
2

05AB1E , 15 14 bytes

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

-1 byte gracias a @MagicOctopusUrn .

Pruébalo en línea.

Explicación:

[             # 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
fuente
[Ð=_#Èi3*>ë<2÷con en =lugar de D,.
Urna mágica del pulpo
@MagicOctopusUrn Ah, eso fue bastante malo de olvidar ... ¡Gracias! :)
Kevin Cruijssen
2

JAEL , 18 bytes

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

Pruébalo en línea!

Eduardo Hoefel
fuente
1
Su enlace permanente no parece estar funcionando. El programa solo imprime la entrada y se detiene.
Dennis
Sí tienes razón. Les pediré a "ellos" que saquen la última versión: P
Eduardo Hoefel
He agregado JAEL a la lista de idiomas de golf . Por favor, avíseme si tengo alguna información incorrecta :-)
ETHproductions
@ETHproductions Muchas gracias: DI creo que podría decir que la especialidad es el paquete de utilidades que ayuda al programador a comprimir el código, pero solo estoy tratando de comercializarlo.
Eduardo Hoefel
1

Wolfram Language (Mathematica) , 35 bytes

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

Pruébalo en línea!

0<Echo@# && ...&es una evaluación de cortocircuito: imprime la entrada #, comprueba si es positiva y, de ser así, la evalúa .... En este caso, ...es #0[3#+1-(5#+3)/2#~Mod~2]; dado que #0(la ranura cero) es la función en sí, esta es una llamada recursiva 3#+1-(5#+3)/2#~Mod~2, que se simplifica a 3#+1cuándo #es par y (#-1)/2cuándo #es impar.

Misha Lavrov
fuente
1

PowerShell, 53 52 bytes

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

Pruébalo en línea!

Editar:
-1 byte gracias a @mazzy

J. Bergmann
fuente
puedes probar en su for(;$i)lugarwhile($i)
mazzy
1

Emojicode 0.5 , 141 bytes

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

Pruébalo en línea!

🐖🎅🏿🍇
🍮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
fuente
1

MathGolf , 12 bytes

{o_¥¿½É3*)}∟

Pruébalo en línea!

Explicación

{             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
fuente
Agregué MathGolf a la lista de juegos de golf. No dudes en corregirme si tengo
algún problema
¡Gracias por agregarlo! Todo me parece bien.
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 

Ensamblado (sintaxis 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 '

Pruébalo en línea!

Logern
fuente
1

R , 66 61 bytes

-5 bytes gracias a Robert S. en la consolidación de ifelse ify en la eliminación de corchetes, y x! = 0 a x> 0

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

en lugar de

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

Pruébalo en línea!

Sumner18
fuente
1
61 bytes
Robert S.
0

perl -Minteger -nlE, 39 bytes

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

fuente
0

Agregar ++ , 38 35 33 bytes

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

Pruébalo en línea!

Cómo funciona

Primero, comenzamos definiendo una función F(X), que toma un solo argumento, realiza la operación invertida de Collatz en Xluego da salida al resultado. Es decir,

F(X)={Xincluso,3X+1Xes impar,X2

Cuando está en modo de función, Add ++ usa un modelo de memoria de pila, de lo contrario se usan variables. Al calcularF(X), la pila se ve inicialmente como S=[X].

Luego duplicamos este valor ( d), para obtenerS=[X,X]. Luego damos la primera opción posible,3X+1( 3*1+), intercambie los dos valores superiores, luego calculeX2, dejando S=[3X+1,X2].

A continuación, empujamos X a Sy calcular el bit de X es decir X%2, dónde un%sidenota el resto al dividirun por si. Esto nos deja conS=[3X+1,X2,(X%2)]. Finalmente, usamos Dpara seleccionar el elemento en el índice especificado por(X%2). Si eso es0 0, devolvemos el primer elemento, es decir 3X+1de lo contrario, devolvemos el segundo elemento, X2.

Eso completa la definición de F(X)Sin embargo, todavía no lo hemos puesto en práctica. Las siguientes tres líneas han cambiado del modo función al modo vainilla, donde operamos con variables. Para ser más precisos, en este programa, solo operamos en una variable, la variable activa , representada por la letra x. Sin embargo,x puede omitirse de los comandos donde obviamente es el otro argumento.

Por ejemplo, +?es idéntico a x+?, y asigna la entrada a x, pero como xes la variable activa , se puede omitir. Luego, sacamos x, luego todo el ciclo while, que se repite durante tanto tiempo comoX0 0. El bucle es muy simple, que consiste en una sola instrucción: $f>x. Todo lo que hace es correrF(X), luego asigne eso a x, actualizando xen cada iteración del bucle.

caird coinheringaahing
fuente
Solo para entender: ¿es la línea de corte parte del código? ¿O es solo para una mejor explicación? Realmente no sé este idioma.
Eduardo Hoefel el
@EduardoHoefel ¿Línea de descanso?
caird coinheringaahing
@cairdcoinheringaahing Los personajes de nueva línea, presumiblemente.
Lynn el
0

Retina 0.8.2 , 46 bytes

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

Pruébalo en línea! Explicación:

.+
$*

Convierte a unario.

{

Repita hasta que el valor deje de cambiar.

*M`1

Imprime el valor en decimal.

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

Si es par, multiplique por 6 y agregue 3.

1(.*)\1
$1

Resta 1 y divide entre 2.

La nueva línea final se puede suprimir agregando un ;antes de {.

Neil
fuente
0

Raqueta , 75 bytes

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

Pruébalo en línea!

Equivalente a la solución Common Lisp de JRowan.

Galen Ivanov
fuente
0

C # (.NET Core) , 62 bytes

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

Pruébalo en línea!

Sin golf:

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)
}
Suricata
fuente