La sequenza di Kuznetsov


18

La sequenza di Kuznetsov

(I made the name up, don't bother with Wikipedia or Google)

Dato qualsiasi numero n > 0, rrappresentiamo il contrario del numero n. Scorrere fino a quando il risultato finale è zero, passando il risultato di ciascuna iterazione nella funzione utilizzando la ricorsione o una metodologia di propria scelta eseguendo l'operazione seguente:

  • Se r > nper quella iterazione il risultato è r % n.
  • Se n > rper quella iterazione il risultato è n % r.
  • Se n % r = 0o r % n = 0, si interrompe l'iterazione.

Prendi il risultato intermedio di ogni esecuzione e memorizzalo in un array per la risposta finale. Il numero iniziale nnon fa parte della sequenza, né lo è 0; gli esempi dovrebbero rendere tutto un po 'più ovvio.

Vediamo un esempio di dove n=32452345.

54325423 % 32452345 = 21873078 # r > n, uses r % n
87037812 % 21873078 = 21418578 # r > n, uses r % n
87581412 % 21418578 = 1907100  # r > n, uses r % n
1907100 % 17091 = 9999         # n > r, uses n % r
9999 % 9999 = 0                # r % n = n % r = 0, terminated

Result: [21873078, 21418578, 1907100, 9999]     

Un altro esempio n=12345678:

87654321 % 12345678 = 1234575 # r > n, uses r % n
5754321 % 1234575 = 816021    # r > n, uses r % n
816021 % 120618 = 92313       # n > r, uses n % r
92313 % 31329 = 29655         # n > r, uses n % r
55692 % 29655 = 26037         # r > n, uses r % n
73062 % 26037 = 20988         # r > n, uses r % n
88902 % 20988 = 4950          # r > n, uses r % n
4950 % 594 = 198              # n > r, uses n % r
891 % 198 = 99                # r > n, uses r % n
99 % 99 = 0                   # r % n = n % r = 0, terminated

Result: [1234575, 816021, 92313, 29655, 26037, 20988, 4950, 198, 99]

Un ultimo esempio n=11000:

11000 % 11 = 0 # n % r = 0, terminated

Result: []

Si tratta delle vittorie con il numero di byte più basso di .


2
I risultati possono essere stampati quando si verificano i calcoli o deve costruire un array?
FlipTack

Suppongo che si applichino le regole di output predefinite, quindi puoi scegliere outputartart (array, numeri visualizzati separati da spazi, ...)
Luis Mendo,

@ Flp.Tkc Non limiterò l'output, purché vengano visualizzati i numeri richiesti.
Magic Octopus Urn

2
Solo una nota che il "rovescio" di un numero è significativo solo rispetto a una base particolare.
David Conrad,

1
@ Sp3000 sorta di; tranne che è necessario prendere il contrario ogni iterazione. Attraverso il calcolo si inserisce solo un numero, non due, e si considera che il secondo sia sempre il contrario del primo.
Tomsmeding,

Risposte:



6

PowerShell v2 +, 89 byte

param($n)for(){$r=-join"$n"["$n".length..0];if(!($n=(($r%$n),($n%$r))[$n-gt$r])){exit}$n}

Soluzione iterativa. Lungo perché non esiste un modo semplice per invertire un array, quindi lo stringiamo e lo indicizziamo all'indietro per archiviarlo $r. Quindi uno pseudo-ternario per estrarre il modulo appropriato e riporlo $nper il round successivo. Tuttavia, se il risultato è zero, significa che lo !($n...)sarà $true, quindi noi exitinvece di $n. I numeri vengono lasciati sulla pipeline e (implicitamente) restituiti come array, ma senza una pipeline incapsulante o salvando i risultati in una variabile, il valore predefinito Write-Outputindica una nuova riga.

Provalo online! (Sì, davvero grave.)
PowerShell è ora su TIO! Devi dargli un secondo o due, perché PowerShell è una bestia di avvio, ma ora si, sì si , possibile verificare il codice PowerShell direttamente nel tuo browser!


Gah, battimi e con lo stesso approccio. Bello!
Briantist,

6

Perl, 43 38 + 1 = 39 byte

Corri con la -nbandiera

say while$_=($;=reverse)>$_?$;%$_:$_%$

Provalo online! Include i due esempi non vuoti.

Grafico esplicativo

-n: Avvolge l'intero programma while(<>){ ... ;} . Questo trasforma il codice sopra nella seguente riga: while(<>){say while$_=($;=reverse)>$_?$;%$_:$_%$;}. Si noti che è stato aggiunto un punto e virgola al finale $, quindi ora diventa un'istanza della variabile $;. Nella condizione di un whileciclo, <>legge automaticamente una riga di input e la salva nella $_variabile. Quindi ora diamo un'occhiata a ciò che l'interprete legge nel whileciclo esterno :

say while$_=($;=reverse)>$_?$;%$_:$_%$;
[op][mod][         condition          ]     #While is acting as a statement modifier.
                                            #It evaluates the operation as long as the condition is truthy.
            ($;=reverse)>$_?$;%$_:$_%$;     #The meat of the program: a ternary operation
            ($;=reverse)                    #The reverse function takes $_ as a parameter by default, and reverses the value.
                                            #The value returned by reverse is stored in the variable $;
                        >$_                 #A condition asking if $% is greater than $_.  Condition of the ternary operation
                           ?$;%$_           #If true, then return $; modulo $_
                                 :$_%$;     #If false, return $_ modulo $;
         $_=                                #Assign the result of the ternary operation back into $_
                                            #If $_ is non-zero, then the condition is true, and while will evaluate the operation
say                                         #Implicitly takes the $_ variable as parameter, and outputs its contents

Codice originale, salvato per i posteri: 43 + 1 = 44 byte

say$_=$%>$_?$%%$_:$_%$%while$_-($%=reverse)

$%>$_?$%%$_:$_%$%Hai scelto la $%variabile apposta solo per questa linea?
Tomsmeding,

Quasi - Salvo anche 1 byte usando un carattere non alfanumerico per l'ultimo carattere prima dell'istruzione while, quindi non ho bisogno di uno spazio. A parte questo - praticamente, sì
Gabriel Benamy, il

5

Pyth, 13 12 byte

t.u|%F_S,s_`

Grazie a @TheBikingViking.

Provalo online: dimostrazione

Il mio vecchio codice:

W
W=Q%F_S,s_`

Provalo online: dimostrazione

Spiegazione:

t.u|%F_S,s_`NNNQ  implicit Ns and Q at the end
               Q  start with N = Q (Q = input number)
        ,         create a pair with the numbers
         s_`N        convert N to string -> reverse-> convert to int
             N       and N
       S          sort
      _           reverse
    %F            fold by modulo
   |          N   or N (if the result is zero use N instead to stop)
 .u               apply this ^ procedure until a value repeats
                  print all intermediate values
 t                except the first one (the original number)

12 byte: t.u|%F_S,s_<backtick>. Test
TheBikingViking

1
@TheBikingViking Grazie, è davvero intelligente.
Jakube,

4

Gelatina , 15 14 13 byte

,ṚḌṢṚ%/
ÇÇпḊ

TryItOnline

Come?

,ṚḌṢṚ%/ - Link 1, iterative procedure: n
,       - pair n with
 Ṛ      - reverse n
  Ḍ     - undecimal (int of digit list)
   Ṣ    - sort
    Ṛ   - reverse
     %/ - reduce with mod

ÇÇпḊ - Main link: n
  п  - collect while
 Ç    - last link as a monad is truthy
Ç     -     last link as a monad
    Ḋ - dequeue (remove the input from the head of the resulting list)

4

Gelatina , 13 12 byte

,ṚḌṢṚ%/Ṅß$Ṡ¡

Questo è un collegamento / funzione monadico che stampa su STDOUT.

Provalo online!

Come funziona

,ṚḌṢṚ%/Ṅß$Ṡ¡  Monadic link. Argument: n

,Ṛ            Pair n and its reversed digit list.
  Ḍ           Convert the digit list into an integer.
   ṢṚ         Sort and reverse.
     %/       Reduce by modulo. Result: m
          Ṡ¡  Do sign(m) times:
       Ṅß$    Print with a newline and call the link recursively.

A cosa serve il piè di pagina? Se rimosso, il codice sembra generare uno 0 finale
Luis Mendo il

È corretto. Il 0 è il valore di ritorno della funzione, che stampa l'interprete se non viene scartata. Secondo questa meta discussione , è permesso.
Dennis,

4

Python 2, 92 87 81 73 61 byte

Soluzione ricorsiva:

def f(n):
    r=int(`n`[::-1]);x=min(r%n,n%r)
    if x:print x;f(x)

Provalo online

Soluzione iterativa: (anche 61 byte )

n=input()
while n:r=int(`n`[::-1]);n=min(r%n,n%r);print n/n*n

Provalo online


La soluzione iterativa che ti ho dato in realtà è di 59 byte, ma non sono sicuro che sia valida perché stampa l'input. Se lo è, allora puoi giocare a golf di 2 byte semplicemente facendo while n:. Altrimenti, puoi farlo con 61 byte .
FlipTack

3

MATL , 16 byte

`tVPUhSPZ}\tt]xx

Provalo online!

Spiegazione

`         % Do...while
  t       %   Duplicate. Takes input implicitly in the first iteration
  VPU     %   Transform the number at the top of the stack by reversing its digits
  hSPZ}   %   Concatenate the two numbers into an array, sort, reverse, split the
          %   array: this moves the smaller number to the top
  \       %   Modulo
  t       %   Duplicate. The original copy is left on the stack for displaying, 
          %   and the duplicate will be used for computing the next number
  t       %   Duplicate. This copy will be used as loop condition: exit if 0
]         % End
xx        % Delete the two zeros at the top. Implicitly display rest of the stack

2

PHP, 78 byte

function a($n){while(($r=strrev($n))&&($n=$r>$n?$r%$n:$n%$r)!=0){echo$n.' ';}}

2

Lotto, 140 byte

@echo off
set/pn=
:l
set/am=n,l=0
:r
set/al=l*10+m%%10,m/=10
if %m% gtr 0 goto r
set/an=l%%n%%l+n%%l%%n
if %n% gtr 0 echo %n%&goto l

Accetta input su STDIN ed emette la sequenza su linee separate. Batch ha istruzioni condizionali (che sono in qualche modo verbose) ma nessuna espressione condizionale, quindi è più facile (nonostante dover citare le %s) per calcolare r%n%r(che è uguale a r%nse n<ro zero se n>r) e n%r%n(che è uguale a n%rse n>ro zero se n<r) e aggiungere insieme.


2

Mathematica, 68 byte

Grazie a Greg Martin per avermi suggerito di usare FixedPointListpiuttosto che NestWhileList:

FixedPointList[Mod[(r=IntegerReverse@#)~Max~#,r~Min~#]&,#][[2;;-4]]&

Il più breve con cui ho potuto ottenere la mia soluzione originale FixedPointListera di 73 byte:

NestWhileList[Mod[(r=IntegerReverse@#)~Max~#,r~Min~#]&,#,#!=0&][[2;;-2]]&

1
Si noti che non si dispone della condizione di terminazione corretta (provare l'input di esempio 11000). Puoi aggirare questo problema passando alla tecnica descritta nel tuo ultimo paragrafo. Ma non vedo come sbarazzarmi di Resto Mostin questo modo. D'altra parte, FixedPointList[ Mod[(r = IntegerReverse@#)~Max~#, r~Min~#] &, #][[2 ;; -4]] &sono solo 68 byte una volta rimossi gli spazi (genera un paio di errori, nbd).
Greg Martin,

Mi ero in qualche modo convinto che span come {a,b,c,d}[[2;;-4]]avrebbero dato un errore piuttosto che l'elenco vuoto (probabilmente ho usato una virgola anziché ;;). Ho imparato qualcosa.
ngenisi,

Puoi sbarazzarti di tutta quella faccenda min / max con un Sort:FixedPointList[-Mod@@Sort@-{#,IntegerReverse@#}&,#][[2;;-4]]&
Martin Ender il

1

JavaScript, 72 70 byte

f=(s,...o)=>(u=s>(z=[...s+''].reverse().join``)?s%z:z%s)?f(u,...o,u):o

console.log(...[32452345, 12345678, 11000].map(x=>f(x)))
.as-console-wrapper{max-height:100%!important}

Modificato:

-2 byte : l'operatore spread attende la concatenazione di stringhe.


1

R, 126 117 byte

x=scan();while(x){y=sort(c(x,as.double(paste(rev(el(strsplit(c(x,""),""))),collapse=""))));if(x<-y[2]%%y[1])print(x)}

Purtroppo, invertire un numero ( as.double(paste(rev(el(strsplit(c(x,""),""))),collapse="")))) è piuttosto prolisso. Il riposo è abbastanza facile. Utilizza sortper verificare indirettamente quale è maggiore.

Il resto è semplice, continua a scorrere fino a x=0e stampa tutti i passaggi.


1

C, 87 byte

t;r;f(n){while(t=n){r=0;while(t)r=10*r+t%10,t/=10;n=r>n?r%n:n%r;if(n)printf("%d ",n);}}

tè temporaneo per l'inversione. Il loop interno sposta di r1 cifra a sinistra e aggiunge l'ultima cifra dit fino a quando non si esaurisce. L'output avviene dopo la prima iterazione e solo se è diverso da zero per impedire la visualizzazione del primo e dell'ultimo elemento.

Ungolfed e utilizzo:

t;r;
f(n){
  while (t = n){
    r = 0;
    while (t)
      r = 10*r + t%10,
      t /= 10; 
    n = r>n ? r%n : n%r;
    if(n)
      printf("%d ",n);
  }
}

0

Mathematica, 64 byte

NestWhileList[#2~If[#<=#2,Mod,#0]~#&[IntegerReverse@#,#]&,#,#>0&]&

Il codice sopra rappresenta una funzione pura che accetta un singolo input e restituisce la sequenza kuznetsovs. La cosa veramente bella di matematica è che puoi mettere strato su strato di funzioni pure ... Mi permetta di spiegare il codice;)

Ogni termine nella sequenza stessa viene calcolato con la funzione seguente, che accetta un input e restituisce il termine successivo.

#2~If[#<=#2,Mod,#0]~#&[IntegerReverse@#,#]&

Il codice IntegerReverse@#genera solo r, il valore invertito. Il codice #2~If[#<=#2,Mod,#0]~#&è una funzione che accetta due input e fa l'operazione mod, oppure inverte gli input e si chiama di nuovo. Un altro modo di scrivere è If[#<=#2, Mod, #0][#2, #]&, o potrebbe essere scritto come una normale funzione come questa:k[a_, b_] := If[a <= b, Mod, k][b, a]


0

Racchetta 180 byte

(let p((n n)(ol'()))(let*((v reverse)(o modulo)
(r(string->number(list->string(v(string->list(number->string n))))))
(m(if(> n r)(o n r)(o r n))))(if(= m 0)(v ol)(p m(cons m ol)))))

Ungolfed:

(define (f n)
  (let loop ((n n)
             (ol '()))
    (let* ((r (string->number
               (list->string
                (reverse
                 (string->list
                  (number->string n))))))
           (m (if (> n r)
                  (modulo n r)
                  (modulo r n))))
      (if (= m 0)
          (reverse ol)
          (loop m (cons m ol))))))

test:

(f 32452345)
(f 12345678)

ouput:

'(21873078 21418578 1907100 9999)
'(1234575 816021 92313 29655 26037 20988 4950 198 99)
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.