Sequência de Kuznetsov


18

Sequência de Kuznetsov

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

Dado qualquer número n > 0, vamos rrepresentar o reverso do número n. Itere até que o resultado final seja zero, passando o resultado de cada iteração de volta para a função usando recursão ou uma metodologia de sua escolha, executando a operação abaixo:

  • Se, r > npara essa iteração, o resultado for r % n.
  • Se, n > rpara essa iteração, o resultado for n % r.
  • Se n % r = 0ou r % n = 0, você encerra a iteração.

Pegue o resultado intermediário de cada execução e armazene-os em uma matriz para a resposta final. O número inicial nnão faz parte da sequência, nem é 0; os exemplos devem tornar tudo um pouco mais óbvio.

Vamos percorrer um exemplo de onde 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]     

Outro exemplo 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]

Um exemplo final n=11000:

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

Result: []

São as vitórias mais baixas em contagem de bytes do .


2
Os resultados podem ser impressos conforme os cálculos ocorrem ou devem ser construídos um array?
FlipTack

Eu diria que o padrão regras de saída aplicar, assim você pode escolher FORMART saída (array, números exibidos separados por espaços, ...)
Luis Mendo

@ Flp.Tkc Não restringirei a saída, desde que os números necessários sejam exibidos.
Magic Octopus Urn

2
Apenas uma observação de que o 'reverso' de um número é significativo apenas em relação a uma base específica.
David Conrad

1
@ Sp3000 mais ou menos; exceto que você precisa fazer o inverso a cada iteração. Você só encadeia um número no cálculo, não dois, e considera o segundo sempre o inverso do primeiro.
tomsmeding

Respostas:



6

PowerShell v2 +, 89 bytes

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

Solução iterativa. Longo, porque não há uma maneira fácil de reverter uma matriz, por isso, a caracterizamos e a indexamos para trás para armazenar $r. Em seguida, um pseudo-ternário para retirar o módulo apropriado e guardar novamente $npara a próxima rodada. No entanto, se o resultado for zero, significa que !($n...)será $true, então, em exitvez de $n. Os números são deixados no pipeline e (implicitamente) retornados como uma matriz, mas sem um pipeline de encapsulamento ou salvando os resultados em uma variável, o padrão Write-Outputadere a uma nova linha.

Experimente online! (Sim, é sério.) O
PowerShell agora está no TIO! Você tem que dar-lhe um segundo ou dois, porque PowerShell é uma besta de inicialização, mas agora você, sim você , pode verificar PowerShell direito código no seu navegador!


Gah, me derrote e com a mesma abordagem. Agradável!
Briantist

6

Perl, 43 38 + 1 = 39 bytes

Corra com a -nbandeira

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

Experimente online! Inclui os dois exemplos não vazios.

Quadro explicativo

-n: Envolve o programa inteiro no while(<>){ ... ;}. Isso transforma o código acima para a seguinte linha: while(<>){say while$_=($;=reverse)>$_?$;%$_:$_%$;}. Observe que um ponto-e-vírgula foi adicionado ao final $, tornando-se agora uma instância da variável $;. Na condição de um whileloop, <>lê automaticamente uma linha de entrada e a salva na $_variável. Então agora vamos ver o que o intérprete lê dentro do whileloop externo :

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

Código original, salvo para a posteridade: 43 + 1 = 44 bytes

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

$%>$_?$%%$_:$_%$%Você escolheu a $%variável de propósito apenas para esta linha?
tomsmeding

Quase - também economizo 1 byte usando um caractere não alfanumérico para o último caractere antes da instrução while, portanto, não preciso de um espaço em branco. Fora isso - praticamente, sim
Gabriel Benamy

5

Pitão, 13 12 bytes

t.u|%F_S,s_`

Graças a @TheBikingViking.

Experimente online: Demonstração

Meu código antigo:

W
W=Q%F_S,s_`

Experimente online: Demonstração

Explicação:

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 bytes: t.u|%F_S,s_<backtick>. Teste
TheBikingViking

1
@TheBikingViking Obrigado, isso é realmente inteligente.
Jakube 9/12

4

Geléia , 15 14 13 bytes

,ṚḌṢṚ%/
ÇÇпḊ

TryItOnline

Quão?

,ṚḌṢṚ%/ - 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

Geléia , 13 12 bytes

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

Este é um link / função monádica que imprime em STDOUT.

Experimente online!

Como funciona

,ṚḌṢṚ%/Ṅß$Ṡ¡  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.

Para que serve o rodapé? Se removido, o código parece gerar um 0 à direita
Luis Mendo

Está correto. O 0 é o valor de retorno da função, que o intérprete imprime se não for descartado. De acordo com esta meta discussão , isso é permitido.
Dennis

4

Python 2, 92 87 81 73 61 bytes

Solução recursiva:

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

Experimente online

Solução iterativa: (também 61 bytes )

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

Experimente online


A solução iterativa que eu lhe dei é na verdade 59 bytes, mas não tenho certeza se é válida porque imprime a entrada. Se for, então você pode jogar golfe de 2 bytes apenas fazendo while n:. Caso contrário, você pode fazê-lo com 61 bytes .
FlipTack

3

MATL , 16 bytes

`tVPUhSPZ}\tt]xx

Experimente online!

Explicação

`         % 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 bytes

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

2

Lote, 140 bytes

@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

Recebe entrada em STDIN e gera a sequência em linhas separadas. O lote possui instruções condicionais (que são um tanto detalhadas), mas nenhuma expressão condicional, portanto, é mais fácil (apesar de ter que citar os %) calcular r%n%r(que é igual a r%nse n<rou zero se n>r) e n%r%n(que é igual a n%rse n>rou zero se n<r) e adicionar eles juntos.


2

Mathematica, 68 bytes

Graças a Greg Martin por sugerir que eu use, em FixedPointListvez de NestWhileList:

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

O mais curto possível com minha solução original FixedPointListfoi 73 bytes:

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

1
Observe que você não possui a condição final correta (tente a entrada de exemplo 11000). Você pode contornar isso mudando para a técnica descrita em seu último parágrafo. Mas não vejo como me livrar Restou Mostdessa maneira. Por outro lado, FixedPointList[ Mod[(r = IntegerReverse@#)~Max~#, r~Min~#] &, #][[2 ;; -4]] &são apenas 68 bytes depois que os espaços são removidos (gera alguns erros, nbd).
Greg Martin

De alguma forma, me convenci de que a extensão como {a,b,c,d}[[2;;-4]]daria um erro em vez da lista vazia (provavelmente usei uma vírgula em vez de ;;). Aprendi alguma coisa.
Ngenisis

Você pode se livrar de todo esse negócio mínimo / máximo com Sort:FixedPointList[-Mod@@Sort@-{#,IntegerReverse@#}&,#][[2;;-4]]&
Martin Ender

1

JavaScript, 72 70 bytes

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}

Editado:

-2 bytes : O operador de propagação aguarda a concatenação da string.


1

R, 126 117 bytes

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)}

Infelizmente, reverter um número ( as.double(paste(rev(el(strsplit(c(x,""),""))),collapse="")))) é bastante prolixo. Descansar é bem fácil. Usa sortpara verificar indiretamente qual é mais alto.

O resto é direto, continua em loop até x=0e imprime todas as etapas.


1

C, 87 bytes

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é temporário para reversão. O loop interno desloca r1 dígito para a esquerda e adiciona o último dígito det até que esteja esgotado. A saída ocorre após a primeira iteração e somente se for diferente de zero para impedir que o primeiro e o último item sejam exibidos.

Ungolfed e uso:

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 bytes

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

O código acima representa uma função pura que recebe uma única entrada e retorna a sequência kuznetsovs. O mais bonito do mathematica é que você pode colocar camadas e mais camadas de funções puras ... Permita-me explicar o código;)

Cada termo na própria sequência é calculado com a função abaixo, que recebe uma entrada e retorna o próximo termo.

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

O código IntegerReverse@#apenas gera r, o valor invertido. O código #2~If[#<=#2,Mod,#0]~#&é uma função que recebe duas entradas e faz a operação mod, ou reverte as entradas e chama a si mesma novamente. Outra maneira de escrever é If[#<=#2, Mod, #0][#2, #]&ou pode ser escrita como uma função regular como esta:k[a_, b_] := If[a <= b, Mod, k][b, a]


0

Raquete 180 bytes

(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))))))

Teste:

(f 32452345)
(f 12345678)

Ouput:

'(21873078 21418578 1907100 9999)
'(1234575 816021 92313 29655 26037 20988 4950 198 99)
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.