Invertire e sottrarre


22

Descrizione della sfida

Prendiamo un numero intero positivo n, invertiamo le sue cifre per ottenere rev(n)e ottenere il valore assoluto della differenza di questi due numeri: |n - rev(n)|(o abs(n - rev(n))).

Esempio:

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

Dopo aver ripetuto l'operazione abbastanza volte, la maggior parte dei numeri diventerà 0(terminando così il ciclo) ...

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

... anche se alcuni numeri (come 1584) rimangono bloccati in un ciclo infinito:

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

Il tuo compito è determinare se un dato numero intero viene bloccato in un ciclo infinito.

Descrizione dell'input

Un numero intero positivo.

Descrizione dell'output

Un valore di verità ( True, 1) se il numero viene bloccato in un ciclo infinito, un valore di falsa ( False, 0) in caso contrario.

Gli appunti

  • Gli zero finali devono essere ommited. vale a dire rev(5020) = 205.
  • Ricorda che si tratta di , quindi rendi il tuo codice il più breve possibile!
  • Sequenza pertinente: A072140


Una nota interessante: è possibile costruire un numero intero arbitrariamente lungo con un ciclo di 2, come descritto nei commenti su A072141 . Il metodo è identico anche per altri periodi, come 12, 14, 17 e 22.
— mbomb007

Risposte:


18

Pyth, 5 byte

4 byte grazie a FryAmTheEggman

uas_`

Suite di test.

Il valore di verità è uno dei numeri nel ciclo.

Il valore di falso è 0.

Spiegazione

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

Buon uso delle variabili di riempimento automatico!
— FryAmTheEggman,

1
* abuso - - - - -
— Leaky Nun,

Come funziona, per qualcuno che non conosce Pyth?
— Fatalizza il

3
come è pyth così breve ma ancora nell'intervallo ASCII ._.
— Downgoat,

3
@Downgoat Perché è Pyth.
— Leaky Nun,

11

Mathematica, 39 37 byte

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

Applica semplicemente i ntempi di trasformazione inversa / sottratta all'input ne quindi controlla se il risultato è 0. Non può mai richiedere più di un 10npassaggio per raggiungere un ciclo, perché la trasformazione non può aumentare il numero di cifre e ci sono meno di 10nnumeri senza più cifre di n. Vedi la prova di Dennis su come ridurre questo limite n.


10

Gelatina , 6 5 byte

ṚḌạµ¡

Provalo online!

sfondo

Questo utilizza il limite superiore di @nnEnder di 10n iterazioni e le seguenti osservazioni.

  1. Vi sono 9 × 10 k - 1 numeri interi positivi n con k cifre.

  2. La differenza di un numero e il suo contrario è sempre un multiplo di 9 , quindi solo 10 k - 1 possono verificarsi dopo la prima iterazione.

  3. Dei multipli, più di 1/10 perde una cifra nella successiva iterazione (per cominciare, tutti che iniziano e terminano con le stesse cifre, e circa il doppio se la prima cifra è né 1 né 9 ), così ci vogliono al massimo 9 × 10 k - 2 per entrare in un ciclo o perdere una cifra.

  4. Applicando lo stesso ragionamento al numero intero risultante di k - 1 cifre e così via, sono necessari al massimo 9 × 10 k - 2 + 9 × 10 k - 2 +… ≤ 10 k - 1 ≤ n iterazioni per inserire un ciclo o raggiungere 0 .

Come funziona

ṚḌạµ¡  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 ha battuto Jelly?
— Leaky Nun,

3
Bene, è un pareggio.
— Dennis,

Questi non sono byte.
— mik

1
@mik Fare clic sul collegamento byte nell'intestazione.
— Dennis,

5

Oracle SQL 11.2, 136 byte

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;

Un-golfed

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 caratteri

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

Usiamo l'argomento sinistro come accumulatore dei valori che abbiamo già visto. Lo inizializziamo su "0", che è una delle due condizioni di terminazione. La guardia ⍵∊⍺:×⍵è letta: "è l'argomento giusto qualcosa che abbiamo già visto (e che include zero)? In tal caso restituire il segno del numero, che è 1 o 0". Altrimenti ricerchiamo chiamando noi stessi con il valore assoluto della sottrazione dopo aver catenato il valore corrente sull'argomento sinistro.


Una rifusione della soluzione Mathematica di Martin Ender segnerebbe 21 caratteri :

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

Si legge: "qual è il segno del risultato dopo aver applicato il desiderato 10n volte"?


4

Python 2, 50 byte

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

Provalo su Ideone .

sfondo

Questo utilizza il limite superiore di @nnEnder di 10n iterazioni e le seguenti osservazioni.

  1. Vi sono 9 × 10 k - 1 numeri interi positivi n con k cifre.

  2. La differenza di un numero e il suo contrario è sempre un multiplo di 9 , quindi solo 10 k - 1 possono verificarsi dopo la prima iterazione.

  3. Dei multipli, più di 1/10 perde una cifra nella successiva iterazione (per cominciare, tutti che iniziano e terminano con le stesse cifre, e circa il doppio se la prima cifra è né 1 né 9 ), così ci vogliono al massimo 9 × 10 k - 2 per entrare in un ciclo o perdere una cifra.

  4. Applicando lo stesso ragionamento al numero intero risultante di k - 1 cifre e così via, sono necessari al massimo 9 × 10 k - 2 + 9 × 10 k - 2 +… ≤ 10 k - 1 ≤ n iterazioni per inserire un ciclo o raggiungere 0 .



3

Pitone, 129 120 96 byte

Se viene rilevata un'eccezione (normalmente l'unica eccezione che può essere generata con questa funzione è un RuntimeError, a causa della ricorsione infinita), stampa 1. Altrimenti, stampa il risultato, 0.

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

Grazie a @LeakyNun
Grazie a @shooqie


È ufficialmente un (bello) abuso di ricorsione infinita.
— Leaky Nun,

return a and rev(a)
— Leaky Nun,

3
Non è possibile ottenere un RuntimeError a causa della ricorsione molto lunga senza che sia necessariamente infinita?
— Fatalizza il

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

È possibile ridurre drasticamente: def rev(n):a=abs(n-int(str(n)[::-1]));return a and rev(a). Inoltre, il nome del metodo è breve (come rinvece di rev)
— shooqie

3

Python, 101 98 byte

Algoritmo di tartaruga e lepre.

La verità è qualsiasi valore nel ciclo, la falsità è 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 esso!


3

Python 2, 85 84 83 byte

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

Un'altra risposta Python. Aggiunge n a un elenco per ogni iterazione e se n è già nell'elenco, viene emesso False. Altrimenti, funziona fino a 0.

Grazie @NonlinearFruit per un byte.


1
Credo che funzioni print n<1(poiché nè sempre non negativo) e salva 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])salva 5 byte
— Leaky Nun

3

05AB1E, 11 8 6 byte

DFÂï-Ä

spiegato

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

Il valore di verità è un numero dal ciclo.
Il valore di Falsy è 0.

Provalo online

Usa il limite superiore spiegato nella risposta Jelly di Dennis

Salvato 2 byte grazie a @Adnan

Nella versione 7.9 di 05AB1E le seguenti soluzioni a 5 byte funzionano come indicato da @Adnan

DFÂ-Ä

Va bene, questo è un po 'strano ma DFÂ-Äfunziona nella versione 7.9 ma non nella versione attuale. Nella versione corrente, è necessario prima convertirlo in un int (come questo DFÂï-Ä), ma è possibile utilizzare la versione 7.9 per renderlo 5 byte: p.
— Adnan,

@Adnan Non riesco a credere di essermi dimenticato della funzione di biforcazione. Mi limiterò alla versione corrente però. Se lo desideri, puoi pubblicare quello 7.9 come risposta separata. Altrimenti lo inserirò come nota.
— Emigna,

Probabilmente non lo pubblicherò, poiché è a solo 1 byte di distanza da questa risposta: p.
— Adnan,

1

Java 7, 161 byte

Ciò richiede un'importazione ma l'ho scritto come una funzione. Gridami nei commenti se in questo scenario è preferito un programma completo. Emette 1 se c'è un ciclo infinito e 0 se il valore arriva 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 che ho visto importazioni e funzioni fatte prima. esempio
— colpisci il

È 1vero?
— Leaky Nun,

1
@LeakyNun 1 non è considerato veritiero in Java ma gli elenchi OP (True, 1) e (False, 0) come output accettabili.
— Colpisci il

@LeakyNun Java ha persino un senso di verità o falsità?
— Neil,

@Neil Java ha la sensazione di sfruttare le opportunità sinergiche nei contesti di mercato verticali - tutto qui
— cat

1

Brachylog , 49 32 23 byte

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

Restituisce trueper loop infiniti e falsealtrimenti.

Questo è un adattamento spudorato dell'algoritmo di Martin Ender.

Risposta precedente, 32 byte

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

Spiegazione della risposta precedente

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 byte

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

Accetta input $n, avvia un forciclo infinito , $a=,0come condizione iniziale (utilizza l'operatore virgola per impostare $aun array di un elemento 0). Questo$a è la nostra gamma di valori già visti.

Ogni iterazione di loop che controlliamo un if. La condizione imposta innanzitutto il valore successivo $ndell'utilizzo dell'inversione di stringa e della [math]::Abschiamata .NET e verifica se tale valore è già -in $a. In tal caso, produciamo $ne exit. Altrimenti, aggiungiamo quel valore all'array e continuiamo il ciclo.

Emette 0valori di input in cui non entra in un ciclo infinito (che è falso in PowerShell) e genera il valore in cui il ciclo è stato rilevato altrimenti (numeri interi diversi da zero sono veritieri). Ad esempio, uscite 2178per input 1584.


0

Haskell, 65 byte

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

Restituisce 0per False e 1per True. Esempio di utilizzo: ([]#) 1584-> 1.

L'approccio ovvio: mantenere un elenco con tutti i risultati visti finora. Calcola il numero successivo fino a quando 0non è nell'elenco.


0

JavaScript (ES6), 75 byte

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

n<0?n=-n:ne n*=n>0||-1anche lavorare. L'algoritmo ricorda in qualche modo la risposta di PowerShell, sebbene si tratti di una formulazione ricorsiva.


0

Rubino, 57 byte

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

L'array inizialmente vuoto htiene traccia dei valori precedentemente raggiunti. Ripetiamo il numero fino a quando non raggiungiamo un valore precedente, quindi controlliamo il valore sull'ultima iterazione. Poiché 0 è un ciclo di 1, sarà 0 se e solo se non esiste un ciclo più grande. Prendo altri 2 byte per convertirlo in un valore booleano perché 0 è vero in Ruby.


0

Perl 6  58 53 33  30 byte

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

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

Spiegazione:

{ # 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
  )[ $_ ]
}

(si basa sull'osservazione precedente che è necessario eseguire questa trasformazione nella maggior parte dei ncasi)


0

Perl 5, 31 29 byte

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

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

Iterate n=|n-rev(n)|n volte, quindi l'output è 0 se non c'è loop,> 0 altrimenti. Dennis ha già dimostrato che questo è abbastanza.

La nuova versione utilizza evale xripete l'operatore anziché il forciclo.


Bella risposta, e benvenuto in PPCG! Si noti che per Perl, le opzioni della riga di comando devono essere inclusi nel byte-count, quindi questo non è abbastanza 30 byte.
— AdmBorkBork,

@TimmyD ok, +1 per -popzione, -lnon è necessario per un singolo input
— mik

0

Matlab, 89 84 byte

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

Approccio semplice: impila tutti i numeri e verifica se un numero è apparso prima.

Spiegazione

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)
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.