Sekwencja Kuzniecowa

18

Sekwencja Kuzniecowa

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

Dając dowolną liczbę n > 0, niech rreprezentuje odwrotność liczby n. Iteruj, aż wynik końcowy wyniesie zero, przekazując wynik każdej iteracji z powrotem do funkcji za pomocą rekurencji lub wybranej metodologii, wykonując poniższą operację:

  • Gdyby r > n dla tej iteracji wynik jest następujący r % n.
  • Gdyby n > r dla tej iteracji wynik jest następujący n % r.
  • Jeśli n % r = 0lubr % n = 0 , zakończysz iterację.

Weź pośredni wynik każdego wykonania i zapisz je w tablicy, aby uzyskać ostateczną odpowiedź. Numer początkowyn nie jest częścią sekwencji, ani nie jest 0; przykłady powinny uczynić wszystko nieco bardziej oczywistym.

Przejdźmy przez przykład gdzie 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]     

Kolejny przykład 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]

Ostatni przykład n=11000:

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

Result: []

Jest to wygrana z najmniejszą liczbą bajtów w .

Urna Magicznej Ośmiornicy
źródło
2
Czy wyniki mogą być drukowane w miarę wykonywania obliczeń, czy też musi konstruować tablicę?
FlipTack,
Zakładam, że obowiązują domyślne reguły wyjściowe, więc możesz wybrać formart wyjściowy (tablica, wyświetlane liczby oddzielone spacjami, ...)
Luis Mendo
@ Flp.Tkc Nie ograniczam wydajności, dopóki wyświetlane są wymagane liczby.
Magic Octopus Urn
2
Tylko uwaga, że ​​„odwrotność” liczby ma znaczenie tylko w odniesieniu do konkretnej podstawy.
David Conrad,
1
@ Sp3000 rodzaj; z wyjątkiem tego, że musisz wykonać odwrotną stronę w każdej iteracji. Podczas obliczeń przewlekasz tylko jedną liczbę, a nie dwie, i bierzesz drugą, aby zawsze była odwrotnością pierwszej.
tomsmeding,

Odpowiedzi:

6

PowerShell v2 +, 89 bajtów

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

Iteracyjne rozwiązanie. Długie, ponieważ nie ma łatwego sposobu na odwrócenie tablicy, więc skreślamy ją i indeksujemy do tyłu, aby ją zapisać $r. Następnie pseudo-trójka, aby wyciągnąć odpowiednie modulo i ponownie zapisać w $nkolejnej rundzie. Jeśli jednak wynik wynosi zero, oznacza to, że tak !($n...)będzie $true, więc myexit zamiast tego $n. Liczby są pozostawione w potoku i (domyślnie) zwrócone jako tablica, ale bez potoku enkapsulacji lub zapisania wyników w zmiennej, domyślnieWrite-Output wstawia nowy wiersz pomiędzy.

Wypróbuj online! (Tak, śmiertelnie poważny.)
PowerShell jest teraz w TIO! Muszę dać mu sekundę lub dwie, ponieważ PowerShell jest bestia na starcie, ale teraz ty, tak ty , może zweryfikować kodu PowerShell prawo w swojej przeglądarce!

AdmBorkBork
źródło
Gah, pobij mnie do tego i tym samym podejściem. Ładny!
briantist
6

Perl, 43 38 + 1 = 39 bajtów

Uruchom z -nflagą

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

Wypróbuj online! Obejmuje dwa niepuste przykłady.

Tabela objaśnień

-n: Zawija cały program while(<>){ ... ;}. Włącza powyższy kod w poniższym wierszu: while(<>){say while$_=($;=reverse)>$_?$;%$_:$_%$;}. Zauważ, że średnik został dodany do końcowego $, więc teraz staje się instancją zmiennej $;. W stanie whilepętli <>automatycznie odczytuje jeden wiersz danych wejściowych i zapisuje go w $_zmiennej. Spójrzmy teraz na to, co interpreter czyta w zewnętrznej whilepętli:

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

Oryginalny kod, zapisany dla potomności: 43 + 1 = 44 bajty

say$_=$%>$_?$%%$_:$_%$%while$_-($%=reverse)
Gabriel Benamy
źródło
$%>$_?$%%$_:$_%$%Czy $%specjalnie dla tej linii wybrałeś zmienną?
tomsmeding,
Prawie - zapisuję również 1 bajt, używając niealfanumerycznego znaku dla ostatniego znaku przed instrukcją while, więc nie potrzebuję spacji. Poza tym -
właściwie
5

Pyth 13 12 bajtów

t.u|%F_S,s_`

Dzięki @TheBikingViking.

Wypróbuj online: Demonstracja

Mój stary kod:

W
W=Q%F_S,s_`

Wypróbuj online: Demonstracja

Wyjaśnienie:

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)
Jakube
źródło
12 bajtów: t.u|%F_S,s_<backtick>. Test
TheBikingViking,
1
@TheBikingViking Dzięki, to naprawdę sprytne.
Jakube,
4

Galaretka , 15 14 13 bajtów

,ṚḌṢṚ%/
ÇÇпḊ

TryItOnline

W jaki sposób?

,ṚḌṢṚ%/ - 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)
Jonathan Allan
źródło
4

Galaretka , 13 12 bajtów

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

Jest to monadyczny link / funkcja, która drukuje do STDOUT.

Wypróbuj online!

Jak to działa

,ṚḌṢṚ%/Ṅß$Ṡ¡  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.
Dennis
źródło
Do czego służy stopka? Po usunięciu kod wydaje się kończyć 0
Luis Mendo
To jest poprawne. 0 stanowi wartość powrotna funkcji, która drukuje tłumacza nie jest odrzucany. Zgodnie z tą meta dyskusją jest to dozwolone.
Dennis,
4

Python 2, 92 87 81 73 61 bajtów

Rozwiązanie rekurencyjne:

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

Wypróbuj online

Rozwiązanie iteracyjne: (także 61 bajtów )

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

Wypróbuj online

mbomb007
źródło
Iteracyjne rozwiązanie, które ci dałem, to w rzeczywistości 59 bajtów, ale nie jestem pewien, czy jest poprawny, ponieważ drukuje dane wejściowe. Jeśli tak, możesz zagrać w golfa o wielkości 2 bajtów while n:. W przeciwnym razie możesz to zrobić z 61 bajtami .
FlipTack,
3

MATL , 16 bajtów

`tVPUhSPZ}\tt]xx

Wypróbuj online!

Wyjaśnienie

`         % 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
Luis Mendo
źródło
2

PHP, 78 bajtów

function a($n){while(($r=strrev($n))&&($n=$r>$n?$r%$n:$n%$r)!=0){echo$n.' ';}}
Wahooka
źródło
2

Partia, 140 bajtów

@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

Pobiera dane wejściowe na STDIN i wysyła sekwencję w osobnych wierszach. Wsad ma instrukcje warunkowe (które są nieco gadatliwe), ale nie ma wyrażeń warunkowych, więc łatwiej jest (pomimo konieczności cytowania %s) obliczyć r%n%r(co jest równe r%nif n<rlub zero jeśli n>r) i n%r%n(który jest równy n%rif n>rlub zero jeśli n<r) i dodać oni razem.

Neil
źródło
2

Mathematica, 68 bajtów

Dzięki Gregowi Martinowi za sugestię, żebym użył FixedPointListzamiast NestWhileList:

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

Najkrótsze, z jakim mogłem uzyskać oryginalne rozwiązanie, FixedPointListto 73 bajty:

NestWhileList[Mod[(r=IntegerReverse@#)~Max~#,r~Min~#]&,#,#!=0&][[2;;-2]]&
ngenisis
źródło
1
Zauważ, że nie masz całkiem odpowiedniego warunku zakończenia (spróbuj przykładowego wejścia 11000). Możesz obejść ten problem, przechodząc do techniki opisanej w ostatnim akapicie. Ale nie widzę, jak się go pozbyć Restani Mostw ten sposób. Z drugiej strony, FixedPointList[ Mod[(r = IntegerReverse@#)~Max~#, r~Min~#] &, #][[2 ;; -4]] &jest tylko 68 bajtów po usunięciu spacji (generuje kilka błędów, nbd).
Greg Martin,
Jakoś przekonałem się, że takie rozpiętości {a,b,c,d}[[2;;-4]]dadzą błąd, a nie pustą listę (prawdopodobnie użyłem przecinka, a nie ;;). Nauczyłem się czegoś.
ngenisis,
Możesz pozbyć się całego tego biznesu min / max dzięki Sort:FixedPointList[-Mod@@Sort@-{#,IntegerReverse@#}&,#][[2;;-4]]&
Martinowi Enderowi
1

JavaScript, 72 70 bajtów

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}

Edytowane:

-2 bajty : operator rozprzestrzeniania czeka na konkatenację łańcucha.

Washington Guedes
źródło
1

R, 126 117 bajtów

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

Niestety odwrócenie liczby ( as.double(paste(rev(el(strsplit(c(x,""),""))),collapse="")))) jest dość trudne. Odpoczynek jest dość łatwy. Używa sortdo pośredniego sprawdzania, która jest wyższa.

Reszta jest prosta, ciągle się zapętla x=0i drukuje wszystkie kroki.

JAD
źródło
1

C, 87 bajtów

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

tjest tymczasowe dla cofania. Wewnętrzna pętla przesuwa r1 cyfrę w lewo i dodaje ostatnią cyfręt aż do wyczerpania. Wyjście następuje po pierwszej iteracji i tylko wtedy, gdy jest niezerowe, aby zapobiec wyświetleniu pierwszego i ostatniego elementu.

Niegolfowane i użytkowanie:

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);
  }
}
Karl Napf
źródło
0

Mathematica, 64 bajty

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

Powyższy kod reprezentuje czystą funkcję, która pobiera pojedyncze dane wejściowe i zwraca sekwencję kuzniecowa. Naprawdę piękne w matematyce jest to, że możesz nakładać warstwę na warstwę czystych funkcji ... Pozwól mi wyjaśnić kod;)

Każdy termin w samej sekwencji jest obliczany za pomocą poniższej funkcji, która pobiera jedno dane wejściowe i zwraca następny.

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

Kod IntegerReverse@#po prostu generuje r, wartość odwróconą. Kod #2~If[#<=#2,Mod,#0]~#&jest funkcją, która pobiera dwa dane wejściowe i albo wykonuje operację mod, albo odwraca dane wejściowe i wywołuje się ponownie. Innym sposobem pisania jest If[#<=#2, Mod, #0][#2, #]&lub można go napisać jako zwykłą funkcję:k[a_, b_] := If[a <= b, Mod, k][b, a]

J. Antonio Perez
źródło
0

Rakieta 180 bajtów

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

Nie golfowany:

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

Testowanie:

(f 32452345)
(f 12345678)

Ouput:

'(21873078 21418578 1907100 9999)
'(1234575 816021 92313 29655 26037 20988 4950 198 99)
rnso
źródło