Invertir y restar


22

Descripción del desafío

Tomemos un número entero positivo n, invierta sus dígitos para obtener rev(n)y obtener el valor absoluto de la diferencia de estos dos números:|n - rev(n)| (o abs(n - rev(n))).

Ejemplo:

n = 5067 
rev(n) = 7605
|n - rev(n)| = |5067 - 7605| = |-2538| = 2538

Después de repetir esta operación muchas veces, la mayoría de los números se convertirán 0(terminando así el ciclo) ...

5067 -> 2538 -> 5814 -> 1629 -> 7632 -> 5265 -> 360 -> 297 -> 495 -> 99 -> 0

... aunque algunos números (como 1584) se atascan en un bucle infinito:

1584 -> 3267 -> 4356 -> 2178 -> 6534 -> 2178 -> 6534 -> 2178 -> 6534 -> ...
                        ^ infinite loop starts here

Su trabajo es determinar si un entero dado se atasca en un bucle infinito.

Descripción de entrada

Un entero positivo.

Descripción de salida

Un valor verdadero ( True, 1) si el número se atasca en un bucle infinito, un valor falso ( False, 0) de lo contrario.

Notas

  • Se deben omitir los ceros finales. es decir rev(5020) = 205.
  • Recuerde que este es el , ¡así que haga su código lo más corto posible!
  • Secuencia relevante: A072140


Una nota interesante: es posible construir un entero arbitrariamente largo con un período de bucle de 2, como se describe en los comentarios sobre A072141 . El método también es idéntico para otros períodos, como 12, 14, 17 y 22.
mbomb007

Respuestas:


18

Pyth, 5 bytes

4 bytes gracias a FryAmTheEggman

uas_`

Banco de pruebas.

El valor verdadero es uno de los números en el bucle.

El valor de falsey es 0.

Explicación

uas_`      Input:Q
uas_`GGQ   Implicit filling of variables.

u      Q   Set G as Q: do this repeatedly until result seen before: Set G as
 a             the absolute difference of
     G             G
    `              convert to string
   _               reverse
  s                convert to integer
      G        and G

Buen uso de las variables de autocompletar!
FryAmTheEggman

1
* abuso - - - - -
Leaky Nun

¿Cómo funciona eso para alguien que no conoce a Pyth?
Fatalize

3
¿Cómo es Pyth tan corto pero todavía en el rango ASCII ._.
Downgoat

3
@Downgoat Porque es pyth.
Leaky Nun

11

Mathematica 39 37 bytes

Nest[Abs[#-IntegerReverse@#]&,#,#]<1&

Simplemente aplica los ntiempos de transformación inversa / resta a la entrada ny luego verifica si el resultado es 0. Nunca puede tomar más que 10npasos para alcanzar un bucle, porque la transformación no puede aumentar el número de dígitos, y hay menos de 10nnúmeros sin más dígitos que n. Vea la prueba de Dennis sobre cómo reducir este límite n.


10

Jalea , 6 5 bytes

ṚḌạµ¡

Pruébalo en línea!

Fondo

Esto utiliza el límite superior de @ MartinEnder de 10n iteraciones y las siguientes observaciones.

  1. Hay 9 × 10 k - 1 enteros positivos n con k dígitos.

  2. La diferencia de un número y su reverso es siempre un múltiplo de 9 , por lo que solo 10 k - 1 de ellos pueden ocurrir después de la primera iteración.

  3. De los múltiplos, más de 1/10 perderán un dígito en la próxima iteración (para empezar, todo eso comienza y termina con los mismos dígitos, y aproximadamente el doble si el primer dígito no es ni 1 ni 9 ), entonces se necesita como máximo 9 × 10 k - 2 para ingresar un bucle o perder un dígito.

  4. Aplicando el mismo razonamiento al eventual entero resultante de k - 1 dígitos y así sucesivamente, toma como máximo 9 × 10 k - 2 + 9 × 10 k - 2 +… ≤ 10 k - 1 ≤ n iteraciones para ingresar un bucle o llegar a 0 .

Cómo funciona

ṚḌạµ¡  Main link. Argument: n

   µ¡  Iteratively apply the chain to the left n times.
Ṛ      Reverse n (casts to digits).
 Ḍ     Undecimal; convert from base 10 to integer.
  ạ    Take the absolute difference of the result and the argument.

11
¿Pyth venció a Jelly?
Leaky Nun

3
Bueno, es un empate.
Dennis

Estos no son bytes.
mik

1
@mik Haga clic en el enlace de bytes en el encabezado.
Dennis

5

Oracle SQL 11.2, 136 bytes

WITH v(n)AS(SELECT :1 FROM DUAL UNION ALL SELECT ABS(n-REVERSE(n||''))FROM v WHERE n>0)CYCLE n SET c TO 0 DEFAULT 1 SELECT MIN(c)FROM v;

Sin golf

WITH v(n) AS
(
  SELECT :1 FROM DUAL
  UNION ALL
  SELECT ABS(n-REVERSE(n||''))FROM v WHERE n>0 
) CYCLE n SET c TO 0 DEFAULT 1
SELECT MIN(c)FROM v

5

APL, 26 caracteres

0∘{⍵∊⍺:×⍵⋄(⍺,⍵)∇|⍵-⍎⌽⍕⍵}

Usamos el argumento izquierdo como el acumulador de los valores que ya hemos visto. Lo inicializamos a "0", que es una de las dos condiciones de terminación. El guardia⍵∊⍺:×⍵ se lee: "¿es el argumento correcto algo que ya hemos visto (y que incluye cero)? Si es así, devuelve el signo del número, que es 1 o 0". De lo contrario, recurramos llamándonos con el valor absoluto de la resta después de haber cateado el valor actual al argumento izquierdo.


Un relanzamiento de la solución de Mathematica por Martin Ender registraría 21 caracteres :

 {×{|⍵-⍎⌽⍕⍵}⍣(10×⍵)⊣⍵}

Se lee: "¿cuál es el signo del resultado después de aplicar las 10 veces deseadas"?


4

Python 2, 50 bytes

n=input()
exec'n=abs(n-int(`n`[::-1]));'*n
print n

Pruébalo en Ideone .

Fondo

Esto utiliza el límite superior de @ MartinEnder de 10n iteraciones y las siguientes observaciones.

  1. Hay 9 × 10 k - 1 enteros positivos n con k dígitos.

  2. La diferencia de un número y su reverso es siempre un múltiplo de 9 , por lo que solo 10 k - 1 de ellos pueden ocurrir después de la primera iteración.

  3. De los múltiplos, más de 1/10 perderán un dígito en la próxima iteración (para empezar, todo eso comienza y termina con los mismos dígitos, y aproximadamente el doble si el primer dígito no es ni 1 ni 9 ), entonces se necesita como máximo 9 × 10 k - 2 para ingresar un bucle o perder un dígito.

  4. Aplicando el mismo razonamiento al eventual entero resultante de k - 1 dígitos y así sucesivamente, toma como máximo 9 × 10 k - 2 + 9 × 10 k - 2 +… ≤ 10 k - 1 ≤ n iteraciones para ingresar un bucle o llegar a 0 .



3

Python, 129 120 96 bytes

Si se detecta una excepción (normalmente la única excepción que se puede lanzar con esta función es un RuntimeError, debido a la recursión infinita), imprime 1. De lo contrario, imprime el resultado, 0.

def r(n):a=abs(n-int(str(n)[::-1]));return a and r(a)
try:print(r(int(input())))
except:print(1)

Gracias a @LeakyNun
Gracias a @shooqie


Eso es oficialmente un abuso (agradable) de recursión infinita.
Leaky Nun

return a and rev(a)
Leaky Nun

3
¿No es posible obtener un RuntimeError debido a que la recursión es muy larga sin que sea necesariamente infinita?
Fatalize

a=[n-x,x-n][n>x]
Leaky Nun

Puede acortar drásticamente: def rev(n):a=abs(n-int(str(n)[::-1]));return a and rev(a). Además, nombre el método como algo corto (como en rlugar de rev)
shooqie

3

Python, 101 98 bytes

Algoritmo de tortuga y liebre.

La verdad es cualquier valor en bucle, Falsey es 0.

g=lambda n:abs(n-int(str(n)[::-1]))
def r(n):
    t=g(n);h=g(t)
    while t-h:h=g(g(h));t=g(t)
    return h

Ideone it!


3

Python 2, 85 84 83 bytes

L=[]
def f(n,L=L):
    if n<1or n in L:print n<1
    else:L+=[n];f(abs(n-int(`n`[::-1])))

Otra respuesta de Python. Agrega n a una lista para cada iteración, y si n ya está en la lista, generaFalse . De lo contrario, funciona hasta 0.

Gracias @NonlinearFruit por un byte.


1
Creo que print n<1funciona (ya nque siempre es no negativo) y ahorra un byte
NonlinearFruit

def f(n,L=[]):¶ if n<1or n in L:print n<1¶ else:f(abs(n-int(`n`[::-1])),L+[n])ahorra 5 bytes
Leaky Nun

3

05AB1E, 11 8 6 bytes

DFÂï-Ä

Explicado

DF          # input number of times do
  Â         # push current number and its reverse
   ï-       # convert reverse to int and subtract
     Ä      # absolute value
            # implicitly print after loop ends

El valor de verdad es un número del bucle.
El valor falso es 0.

Pruébalo en línea

Utiliza el límite superior explicado en la respuesta de Dennis 'Jelly

Guardado 2 bytes gracias a @Adnan

En la versión 7.9 de 05AB1E, las siguientes soluciones de 5 bytes funcionan según lo indicado por @Adnan

DFÂ-Ä

De acuerdo, esto es un poco extraño, pero DFÂ-Äfunciona en la versión 7.9 pero no en la versión actual. En la versión actual, primero debe convertirlo a un int (como este DFÂï-Ä), pero puede usar la versión 7.9 para convertirlo en 5 bytes: p.
Adnan

@Adnan No puedo creer que haya olvidado la función de bifurcación. Sin embargo, me quedaré con la versión actual. Si lo desea, puede publicar el 7.9 como respuesta por separado. De lo contrario, lo pondré como nota.
Emigna

Probablemente no lo publique, ya que está a solo 1 byte de esta respuesta: p.
Adnan

1

Java 7, 161 bytes

Esto requiere una importación, pero lo escribí como una función. Grítame en los comentarios si se prefiere un programa completo en este escenario. Emite 1 si hay un bucle infinito y 0 si el valor llega a 0.

import java.util.*;int z(int a){int o,r,c=a;Set s=new HashSet();while(c!=0){for(r=0,o=c;o!=0;r=r*10+o%10,o/=10);c=Math.abs(c-r);if(!s.add(c))return 1;}return 0;}

Notando que he visto importaciones y funciones hechas antes. ejemplo
Poke

Es 1verdad?
Leaky Nun

1
@LeakyNun 1 no se considera verdadero en Java, pero OP enumera (Verdadero, 1) y (Falso, 0) como resultados aceptables.
Poke

@LeakyNun ¿Java incluso tiene un sentido de verdad o falsedad?
Neil

@Neil Java tiene un sentido de aprovechar las oportunidades sinérgicas en contextos de mercado vertical - eso es todo
gato

1

Brachylog , 49 32 23 bytes

:10*N,?:N:{r:?-+.}itT'0

Devuelve truepara bucles infinitos y de falseotra manera.

Esta es una adaptación descarada del algoritmo de Martin Ender.

Respuesta anterior, 32 bytes

g{tTr:T-+U(0!\;?:ImU;?:[U]c:1&)}

Explicación de la respuesta anterior.

g{                             } Call predicate with [Input] as input
  tT                             T is the last element of Input
    r:T-                         Subtract T from the reverse of T
        +U                       U is the absolute value of T
          (0!\                   If U is 0, return false
              ;                  Or
               ?:ImU             If U is in Input, return true
                    ;            Or
                     ?:[U]c:1&)  Recursive call with U concatenated to the Input

0

PowerShell v2 +, 94 bytes

param($n)for($a=,0;){if(($n=[math]::Abs($n-(-join"$n"["$n".length..0])))-in$a){$n;exit}$a+=$n}

Toma entrada $n, inicia un forbucle infinito , con $a=,0la condición inicial (esto usa el operador de coma para establecer $auna matriz de un elemento 0). Este $aes nuestro conjunto de valores ya vistos.

Cada iteración de bucle verificamos un if. La condición primero establece el siguiente valor de $nusar reversión de cadenas y la [math]::Absllamada .NET, y verifica si ese valor ya lo es -in $a. Si es así, sacamos $nyexit . De lo contrario, agregamos ese valor a la matriz y continuamos el ciclo.

Emite 0los valores de entrada donde no entra en un bucle infinito (que es falso en PowerShell) y emite el valor donde el bucle se encontró de otra manera (los enteros distintos de cero son verdaderos). Por ejemplo, salidas 2178para entrada 1584.


0

Haskell, 65 bytes

_#0=0
a#n|elem n a=1|1<2=(n:a)#abs(n-(read$reverse$show n))
([]#)

Devoluciones 0 para Falso y 1para Verdadero. Ejemplo de uso: ([]#) 1584-> 1.

El enfoque obvio: mantener una lista con todos los resultados vistos hasta ahora. Calcule el siguiente número hasta0 o esté en la lista.


0

JavaScript (ES6), 75 bytes

f=(n,...a)=>a.includes(n=n<0?-n:n)?n:f([...n+``].reverse().join``-n,n,...a)

n<0?n=-n:ny n*=n>0||-1tambien trabajo. Algoritmo se parece un poco a la respuesta de PowerShell, aunque esta es una formulación recursiva.


0

Ruby, 57 bytes

->n,*h{h[n]=n=(n-"#{n}".reverse.to_i).abs until h[n];n>0}

La matriz inicialmente vacía hrastrea los valores previamente alcanzados. Repetimos el número hasta que alcanzamos un valor anterior, luego verificamos el valor en la última iteración. Como 0 es un ciclo de 1, será 0 si y solo si no hay un ciclo mayor. Tomo 2 bytes adicionales para convertir esto a un booleano porque 0 es verdadero en Ruby.


0

Perl 6  58 53 33  30 bytes

sub {$/=%;$^a,{return ?1 if $/{$_}++;abs $_-.flip}...0;?0}
{$/=%;?($_,{last if $/{$_}++;abs $_-.flip}...0)[*-1]}
{?($_,{abs $_-.flip}...0)[10**$_]}

{?($_,{abs $_-.flip}...0)[$_]}

Explicación:

{ # block lambda with implicit parameter $_

  # coerce the following to Bool
  # ( False for Nil or 0, True otherwise )
  ?

  (

    $_, # start a sequence with the input

    # block lambda with implicit parameter $_
    # subtracts the previous value in the sequence and its reverse
    # ( .flip is short for $_.flip where a term is expected )
    { abs $_ - .flip } 

    ... # repeat that lambda
    0   # until you get 0

  # get the element indexed with the block's input
  # may be 0, Nil, or a number that is part of a repeating sequence
  )[ $_ ]
}

(se basa en la observación anterior de que solo necesita hacer esta transformación la mayoría de las nveces)


0

Perl 5, 31 29 bytes

perl -pe'for$x(1..$_){$_=abs$_-reverse}'

perl -pe'eval"\$_=abs\$_-reverse;"x$_'

Se itera n=|n-rev(n)|n veces, por lo que la salida es 0 si no hay bucle,> 0 en caso contrario. Dennis ya demostró que esto es suficiente.

La nueva versión usa evaly xrepite el operador en lugar del forbucle.


Buena respuesta, y bienvenido a PPCG! Tenga en cuenta que para Perl, las opciones de la línea de comandos deben incluirse en su recuento de bytes, por lo que no son 30 bytes.
AdmBorkBork 01 de

@TimmyD ok, +1 para la -popción, -lno es necesario para una sola entrada
mik

0

Matlab, 89 84 bytes

n=input('');z=n;while n
z=abs(z-str2num(fliplr(num2str(z))));n=[n z]*all(n~=z);end
z

Enfoque simple: apila todos los números y comprueba si un número apareció antes.

Explicación

n=input('');z=n;  -- take input, initiate z
while n           -- n is said to be positive
z=abs(z-str2num(fliplr(num2str(z)))) -- calculate the "reverse and substract"
n=[n z]           -- put the value at the end of the vector
       *all(n~=z) -- make the n all zeroes if z is previously in the vector (break the loop)
end
z                 -- print z (0 when not entered loop, >0 otherwise)
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.