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é 19 ), 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é 19 ), 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.