Imprime los números de Super Collatz


22

La secuencia de Collatz (también llamada problema 3x + 1) es donde comienzas con cualquier número entero positivo, para este ejemplo usaremos 10 y le aplicaremos este conjunto de pasos:

if n is even:
    Divide it by 2
if n is odd:
    Multiply it by 3 and add 1
repeat until n = 1

10 es par, entonces dividimos entre 2 para obtener 5. 5 es impar, por lo que multiplicamos por 3 y sumamos 1 para obtener 16. 16 es par, así que córtalo por la mitad para obtener 8. La mitad de 8 es 4, la mitad de 4 es 2, y la mitad de 2 es 1. Como esto nos llevó a 6 pasos, decimos que 10 tiene una distancia de parada de 6.

Un número de Super Collatz es un número cuya distancia de frenado es mayor que la distancia de frenado de cada número más pequeño que él. Por ejemplo, 6 es un número de Super Collatz ya que 6 tiene una distancia de detención de 8, 5 tiene una distancia de detención de 5, 4 tiene 2, 3 tiene 7, 2 tiene 1 y 1 tiene 0. ( A006877 en el OEIS) Debe tome un número n como entrada y haga salir todos los números de Super Collatz hasta n .

Reglas

  • El programa completo o la función es aceptable.

  • No puede calcular previamente ni codificar la secuencia de Super Collatz.

  • Puede tomar la entrada en cualquier formato razonable.

  • La salida puede devolverse como una lista desde la función, o imprimirse en STDOUT o en un archivo. Lo que sea más conveniente.

  • Las entradas inválidas (no números, decimales, números negativos, etc.) resultan en un comportamiento indefinido.

Muestra de pitón sin golf

def collatzDist(n):
    if n == 1:
        return 0
    if n % 2 == 0:
        return 1 + collatzDist(n / 2)
    return 1 + collatzDist((n * 3) + 1)

n = input()

max = -1
superCollatz = []
for i in range(1, n + 1):
    dist = collatzDist(i)
    if dist > max:
        superCollatz.append(i)
        max = dist 

print superCollatz

Muestra IO:

#in       #out
 4     --> 1, 2, 3
 50    --> 1, 2, 3, 6, 7, 9, 18, 25, 27
 0     --> invalid
 10000 --> 1, 2, 3, 6, 7, 9, 18, 25, 27, 54, 73, 97, 129, 171, 231, 313, 327, 649, 703, 871, 1161, 2223, 2463, 2919, 3711, 6171

También aquí están los primeros 44 números de Super Collatz:

1, 2, 3, 6, 7, 9, 18, 25, 27, 54, 73, 97, 129, 171, 231, 313, 327, 649, 703, 871, 1161, 2223, 2463, 2919, 3711, 6171, 10971, 13255, 17647, 23529, 26623, 34239, 35655, 52527, 77031, 106239, 142587, 156159, 216367, 230631, 410011, 511935, 626331, 837799

66
Además, si alguien puede encontrar un número con una distancia de frenado infinita (nunca llega a 1), le daré la mayor recompensa que pueda ofrecer. = D
DJMcMayhem

1
También lo harán muchos matemáticos ...: P
Rɪᴋᴇʀ


55
Esto es solo una conjetura, pero sospecho que la regla 2 es un hecho matemático más que una restricción de desafío.
trichoplax

1
"Debe tomar un número n como entrada, y sacar todos los números de Super Collatz hasta n" Entonces, si entiendo esto correctamente, ¿NO pide que salga el primer número de n super collatz? Porque eso es lo que hace la respuesta de Pyth, por ejemplo, así que creo que no está lo suficientemente claro.
Fatalize

Respuestas:


1

Pyth, 23 bytes

q#eol.u@,/N2h*N3NN)STSQ

Demostración

Esto funciona tomando el máximo del rango hasta cada número por su distancia de parada de Collatz, y verificando si ese máximo es el número en cuestión.


2

Python 2, 104 bytes

c=lambda x:x>1and 1+c([x/2,x*3+1][x%2])
lambda n:[1]+[x for x in range(2,n)if c(x)>max(map(c,range(x)))]

ces una función auxiliar que calcula la distancia de Collatz para un entero dado. La lambda sin nombre es la función principal, que calcula los números de Super Collatz hasta (pero sin incluir) la entrada.


2

Dyalog APL , 41 bytes

(∪⊢⍳⌈\)≢∘{1=⍵:⍬⋄2|⊃⌽⍵:⍵,∇1+3×⍵⋄⍵,∇⍵÷2}¨∘⍳

Una función sin nombre. Nombre o paréntesis para aplicar.

Casos de prueba:

       ((∪⊢⍳⌈\)≢∘{1=⍵:⍬ ⋄ 2|⊃⌽⍵:⍵,∇ 1+3×⍵ ⋄ ⍵,∇ ⍵÷2}¨∘⍳)¨4 50 10000
┌─────┬────────────────────┬───────────────────────────────────────────────────────────────────────────────────────────┐
│1 2 3│1 2 3 6 7 9 18 25 27│1 2 3 6 7 9 18 25 27 54 73 97 129 171 231 313 327 649 703 871 1161 2223 2463 2919 3711 6171│
└─────┴────────────────────┴───────────────────────────────────────────────────────────────────────────────────────────┘

0 da como resultado un comportamiento indefinido.


1

ES6, 86 83 bytes

n=>(i=m=0,c=n=>n<3?n:c(n&1?n*3+1:n/2)+1,[for(x of Array(n))if(c(++i)>m&&(m=c(i)))i])

Editar: guardado 3 bytes al cambiar de filteruna comprensión de matriz.


1

Haskell, 84 bytes

c 1=0;c x|odd x=1+c(3*x+1)|0<1=1+c(div x 2)
f x=[n|n<-[1..x],all(c n>)$c<$>[1..n-1]]

Esto es masivamente lento, por supuesto, ¡pero funciona!


1

Oracle SQL 11.2, 329 bytes

WITH q(s,i)AS(SELECT LEVEL s,LEVEL i FROM DUAL CONNECT BY LEVEL<=:1 UNION ALL SELECT s,DECODE(MOD(i,2),0,i/2,i*3+1)i FROM q WHERE i<>1),v AS(SELECT s,COUNT(*)-1 d FROM q GROUP BY s),m AS(SELECT s,d,MAX(d)OVER(ORDER BY s ROWS BETWEEN UNBOUNDED PRECEDING AND 1 PRECEDING)m FROM v)SELECT s FROM m WHERE(d>m OR s=1)AND:1>0ORDER BY 1;

Versión sin golf

WITH q(s,i) AS 
  (
    SELECT LEVEL s, LEVEL i 
    FROM DUAL CONNECT BY LEVEL <= :1
    UNION ALL 
    SELECT q.s, DECODE(MOD(i,2),0,i/2,i*3+1)i FROM q WHERE q.i <> 1
  )
, v AS (SELECT s, COUNT(*)-1 d FROM q GROUP BY s)
, m AS (SELECT s, d, MAX(d)OVER(ORDER BY s ROWS BETWEEN UNBOUNDED PRECEDING AND 1 PRECEDING) m FROM v)
SELECT * FROM m WHERE (d>m OR s=1) AND :1>0
ORDER BY 1;

La vista q es una vista recursiva verdadera (no una consulta jerárquica con CONNECT BY) que calcula todos los pasos hacia 1 para cada número entero entre 1 y: 1.

La vista v calcula las distancias de frenado.

La vista m utiliza la versión analítica de MAX para aplicarla a todas las filas anteriores, excluyendo la fila actual. De esa manera, para cada número entero, sabemos que es la distancia de frenado y la mayor distancia de frenado actual.

La consulta final verifica si la distancia de detención es mayor que la mayor distancia de detención. Y agrega algunos trucos para manejar 1 y el caso especial de: 1 que tiene un valor de 0.


0

MATL , 37 bytes

:"@tqX`t0)t2\?3*Q}2/]ht0)q]n]N$htY>=f

Pruébalo en línea!

:         % vector [1,2,...N], where N is implicit input
"         % for each number in that range
  @       %   push that number, k
  tq      %   truthy iff k is not 1
  X`      %   while...do loop
    t0)   %     pick first number of array
    t2\   %     is it odd?
    ?     %     if so:
      3*Q %       multiply by 3 and add 1
    }     %     else
      2/  %       divide by 2
    ]     %     end if
    h     %     concatenate into array with previous numbers
    t0)q  %     duplicate, pick last number, is it 1? Leave that as while condition
  ]       %   end while
  n       %   number of elements of array. This is the stopping distance for k
]         % end for
N$h       % concatenate all stopping distances into an array
tY>       % duplicate and compute cumulative maximum
=f        % indices of matching elements. Implicitly display

0

𝔼𝕊𝕄𝕚𝕟, 30 caracteres / 38 bytes

⩥ïⓜМȬ⧺$,a=[])⋎⟮aꝈ-1⟯>ɐ⅋(ɐ=Ⅰ,ᵖ$

Try it here (Firefox only).

La única razón por la que no publiqué esto antes fue porque no tenía claras las especificaciones. Utiliza una codificación personalizada que codifica caracteres de 10 bits.

Explicación

⩥ïⓜcrea un rango [0,input)para mapear. МȬ⧺$,a=[])genera números de Collatz en una matriz vacía y ⋎⟮aꝈ-1⟯>ɐusa la matriz de números de Collatz para obtener la distancia de frenado y verificar si es mayor que la distancia de frenado máxima anterior. Si es así, ⅋(ɐ=Ⅰ,ᵖ$hace que la distancia de frenado actual sea la distancia de frenado máxima y empuja el elemento actual en el rango a la pila. Después, los elementos de la pila se imprimen implícitamente.


Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.