Inverser et soustraire

22

Description du défi

Prenons un entier positif n, inversons ses chiffres pour obtenir rev(n)et obtenir la valeur absolue de la différence de ces deux nombres: |n - rev(n)|(ou abs(n - rev(n))).

Exemple:

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

Après avoir répété cette opération suffisamment de fois, la plupart des nombres deviendront 0(terminant ainsi la boucle) ...

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

... bien que certains nombres (comme 1584) restent coincés dans une boucle infinie:

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

Votre travail consiste à déterminer si un entier donné est bloqué dans une boucle infinie.

Description d'entrée

Un entier positif.

Description de la sortie

Une valeur vraie ( True, 1) si le nombre se coince dans une boucle infinie, une valeur fausse ( False, 0) sinon.

Remarques

  • Les zéros à la fin doivent être supprimés. ie rev(5020) = 205.
  • N'oubliez pas qu'il s'agit de , alors faites votre code aussi court que possible!
  • Séquence pertinente: A072140
shooqie
la source
Une note intéressante: il est possible de construire un entier arbitrairement long avec une période de bouclage de 2, comme décrit dans les commentaires sur A072141 . La méthode est également identique pour les autres périodes, comme les 12, 14, 17 et 22.
mbomb007

Réponses:

18

Pyth, 5 octets

4 octets grâce à FryAmTheEggman

uas_`

Suite de tests.

La valeur véridique est l'un des nombres de la boucle.

La valeur de falsey est 0.

Explication

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
Leaky Nun
la source
Bonne utilisation des variables de remplissage automatique!
FryAmTheEggman
1
* abus - - - - -
Leaky Nun
Comment ça marche, pour quelqu'un qui ne connaît pas Pyth?
Fatalize
3
comment le pyth est-il si court mais toujours dans la gamme ASCII ._.
Downgoat
3
@Downgoat Parce que c'est pyth.
Leaky Nun
11

Mathematica, 39 37 octets

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

Applique simplement les ntemps de transformation inverse / soustraire à l'entrée n, puis vérifie si le résultat est 0. Il ne peut jamais prendre plus de 10nétapes pour atteindre une boucle, car la transformation ne peut pas augmenter le nombre de chiffres, et il y a moins de 10nnombres sans plus de chiffres que n. Voir la preuve de Dennis pour savoir comment réduire cette limite à n.

Martin Ender
la source
10

Gelée , 6 5 octets

ṚḌạµ¡

Essayez-le en ligne!

Contexte

Cela utilise la limite supérieure de @ MartinEnder de 10n itérations et les observations suivantes.

  1. Il y a 9 × 10 k - 1 entiers positifs n avec k chiffres.

  2. La différence d'un nombre et son inverse est toujours un multiple de 9 , donc seulement 10 k - 1 d'entre eux peuvent se produire après la première itération.

  3. Parmi les multiples, plus de 1/10 va perdre un chiffre dans la prochaine itération (pour commencer, tout ce début et fin avec les mêmes chiffres, et à peu près deux fois plus nombreux si le premier chiffre est ni 1 ni 9 ), de sorte il faut au plus 9 × 10 k - 2 pour entrer dans une boucle ou perdre un chiffre.

  4. En appliquant le même raisonnement à l'entier résultant résultant de k - 1 chiffres et ainsi de suite, il faut au plus 9 × 10 k - 2 + 9 × 10 k - 2 +… ≤ 10 k - 1 ≤ n itérations pour entrer dans une boucle ou atteindre 0 .

Comment ça marche

ṚḌạµ¡  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.
Dennis
la source
11
Pyth a-t-il battu Jelly?
Leaky Nun
3
Eh bien, c'est une cravate.
Dennis
Ce ne sont pas des octets.
mik
1
@mik Veuillez cliquer sur le lien octets dans l'en-tête.
Dennis
5

Oracle SQL 11.2, 136 octets

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;

Non 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
Jeto
la source
5

APL, 26 caractères

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

Nous utilisons l'argument de gauche comme accumulateur des valeurs que nous avons déjà vues. Nous l'initialisons à "0", qui est l'une des deux conditions de terminaison. Le gardien ⍵∊⍺:×⍵se lit: "est-ce le bon argument que nous avons déjà vu (et cela inclut zéro)? Si c'est le cas, renvoyez le signe du nombre, c'est-à-dire 1 ou 0". Sinon, reprenons en nous appelant la valeur absolue de la soustraction après avoir caténé la valeur courante à l'argument de gauche.


Une refonte de la solution Mathematica par Martin Ender cadrerait à 21 caractères :

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

Il se lit: "quel est le signe du résultat après avoir appliqué les 10n fois voulu"?

lstefano
la source
4

Python 2, 50 octets

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

Testez-le sur Ideone .

Contexte

Cela utilise la limite supérieure de @ MartinEnder de 10n itérations et les observations suivantes.

  1. Il y a 9 × 10 k - 1 entiers positifs n avec k chiffres.

  2. La différence d'un nombre et son inverse est toujours un multiple de 9 , donc seulement 10 k - 1 d'entre eux peuvent se produire après la première itération.

  3. Parmi les multiples, plus de 1/10 va perdre un chiffre dans la prochaine itération (pour commencer, tout ce début et fin avec les mêmes chiffres, et à peu près deux fois plus nombreux si le premier chiffre est ni 1 ni 9 ), de sorte il faut au plus 9 × 10 k - 2 pour entrer dans une boucle ou perdre un chiffre.

  4. En appliquant le même raisonnement à l'entier résultant résultant de k - 1 chiffres et ainsi de suite, il faut au plus 9 × 10 k - 2 + 9 × 10 k - 2 +… ≤ 10 k - 1 ≤ n itérations pour entrer dans une boucle ou atteindre 0 .

Dennis
la source
3

Python, 129 120 96 octets

Si une exception est interceptée (normalement la seule exception qui peut être levée avec cette fonction est une RuntimeError, en raison de la récursivité infinie), imprimez 1. Sinon, imprimez le résultat, 0.

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

Merci à @LeakyNun
Merci à @shooqie

TuxCrafting
la source
C'est officiellement un (gentil) abus de récursion infinie.
Leaky Nun
return a and rev(a)
Leaky Nun
3
N'est-il pas possible d'obtenir une RuntimeError car la récursivité est très longue sans être nécessairement infinie?
Fatalize
a=[n-x,x-n][n>x]
Leaky Nun
Vous pouvez raccourcir considérablement: def rev(n):a=abs(n-int(str(n)[::-1]));return a and rev(a). Aussi, nommez la méthode quelque chose de court (comme rau lieu de rev)
shooqie
3

Python, 101 98 octets

Algorithme de tortue et de lièvre.

Truthy est n'importe quelle valeur en boucle, falsey est 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!

Leaky Nun
la source
3

Python 2, 85 84 83 octets

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

Une autre réponse Python. Il ajoute n à une liste pour chaque itération, et si n est déjà dans la liste, il génèreFalse . Sinon, cela fonctionne jusqu'à 0.

Merci @NonlinearFruit pour un octet.

atlasologue
la source
1
Je crois que cela print n<1fonctionne (car il nest toujours non négatif) et qu'il enregistre un octet
NonlinearFruit
def f(n,L=[]):¶ if n<1or n in L:print n<1¶ else:f(abs(n-int(`n`[::-1])),L+[n])enregistre 5 octets
Leaky Nun
3

05AB1E, 11 8 6 octets

DFÂï-Ä

Expliqué

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

La valeur vraie est un nombre de la boucle.
La valeur de la fausse valeur est 0.

Essayez-le en ligne

Utilise la borne supérieure expliquée dans la réponse de Dennis 'Jelly

Sauvegardé 2 octets grâce à @Adnan

Dans la version 7.9 de 05AB1E, les solutions à 5 octets suivantes fonctionnent comme indiqué par @Adnan

DFÂ-Ä
Emigna
la source
D'accord, c'est un peu un golf bizarre mais DFÂ-Äfonctionne dans la version 7.9 mais pas dans la version actuelle. Dans la version actuelle, vous devez d'abord le convertir en entier (comme celui-ci DFÂï-Ä), mais vous pouvez utiliser la version 7.9 pour lui donner 5 octets: p.
Adnan
@Adnan Je n'arrive pas à croire que j'ai oublié la fonction de bifurcation. Je m'en tiendrai à la version actuelle. Vous pouvez poster celui de 7,9 comme réponse séparée si vous le souhaitez. Sinon, je le mettrai en note.
Emigna
Je ne le posterai probablement pas, car ce n'est qu'à 1 octet de cette réponse: p.
Adnan
1

Java 7, 161 octets

Cela nécessite une importation mais je l'ai écrit en fonction. Criez-moi dans les commentaires si un programme complet est préféré dans ce scénario. Affiche 1 s'il y a une boucle infinie et 0 si la valeur atteint 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;}
Poussée
la source
Notant que j'ai déjà vu des importations et des fonctions effectuées. exemple
Poke
Est-ce 1vrai?
Leaky Nun
1
@LeakyNun 1 n'est pas considéré comme véridique en java mais OP répertorie (True, 1) et (False, 0) comme sorties acceptables.
Poke
@LeakyNun Java a-t-il même un sens de la vérité ou de la fausseté?
Neil
@Neil Java a le sens de tirer parti des opportunités synergiques dans des contextes de marché verticaux - c'est tout
cat
1

Brachylog , 49 32 23 octets

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

Retourne truepour les boucles infinies et falseautrement.

Il s'agit d'une adaptation éhontée de l'algorithme de Martin Ender.

Réponse précédente, 32 octets

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

Explication de la réponse précédente

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
Fatalize
la source
0

PowerShell v2 +, 94 octets

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

Prend une entrée $n, démarre une forboucle infinie , avec$a=,0 comme condition initiale (cela utilise l'opérateur virgule pour définir $aun tableau d'un élément, 0). Ceci $aest notre tableau de valeurs déjà vues.

Chaque itération de boucle que nous vérifions if. La condition définit d'abord la valeur suivante de l' $nutilisation de l'inversion de chaîne et de l' [math]::Absappel .NET, et vérifie si cette valeur est déjà-in $a . Si oui, nous sortons $net exit. Sinon, nous ajoutons cette valeur au tableau et continuons la boucle.

Sorties 0pour les valeurs d'entrée où elle ne va pas dans une boucle infinie (ce qui est falsey dans PowerShell) et sorties la valeur où la boucle a été rencontrée autrement (les entiers non nuls sont vrais). Par exemple, sorties 2178pour entrée 1584.

AdmBorkBork
la source
0

Haskell, 65 octets

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

Renvoie 0False et 1True. Exemple d'utilisation: ([]#) 1584-> 1.

L'approche évidente: garder une liste avec tous les résultats observés jusqu'à présent. Calculez le nombre suivant jusqu'à ce 0qu'il soit dans la liste.

nimi
la source
0

JavaScript (ES6), 75 octets

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

n<0?n=-n:net n*=n>0||-1aussi travailler. L'algorithme ressemble quelque peu à la réponse PowerShell, bien qu'il s'agisse d'une formulation récursive.

Neil
la source
0

Rubis, 57 octets

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

Le tableau initialement vide hsuit les valeurs précédemment atteintes. Nous itérons le nombre jusqu'à ce que nous atteignions une valeur précédente, puis vérifions la valeur à la dernière itération. Puisque 0 est un cycle de 1, ce sera 0 si et seulement s'il n'y a pas de cycle plus grand. Je prends 2 octets supplémentaires pour convertir cela en un booléen car 0 est vrai en Ruby.

histocrate
la source
0

Perl 6  58 53 33  30 octets

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

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

Explication:

{ # 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 fonde sur l'observation précédente selon laquelle il vous suffit d'effectuer cette transformation la plupart du ntemps)

Brad Gilbert b2gills
la source
0

Perl 5, 31 29 octets

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

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

Il itère n=|n-rev(n)|n fois, donc la sortie est 0 s'il n'y a pas de boucle,> 0 sinon. Dennis a déjà prouvé que cela suffisait.

La nouvelle version utilise evalet xrépète l'opérateur au lieu de la forboucle.

mik
la source
Bonne réponse et bienvenue chez PPCG! Notez que pour Perl, les options de ligne de commande doivent être incluses dans votre nombre d'octets, donc ce n'est pas tout à fait 30 octets.
AdmBorkBork
@TimmyD ok, +1 pour l' -poption, -ln'est pas nécessaire pour une seule entrée
mik
0

Matlab, 89 84 octets

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

Approche simple - empile tous les numéros et vérifie si un numéro est apparu avant.

Explication

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)
pajonk
la source