Послідовність Кузнецова


18

Послідовність Кузнецова

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

Давши будь-яке число n > 0, нехай rпредставляє зворотну сторону числа n. Ітераціюйте, поки кінцевий результат не дорівнює нулю, передаючи результат кожної ітерації назад у функцію за допомогою рекурсії або методології на ваш вибір, виконавши нижчеописану операцію:

  • Якщо r > nдля цієї ітерації результат є r % n.
  • Якщо n > rдля цієї ітерації результат є n % r.
  • Якщо n % r = 0або r % n = 0, ви припиняєте ітерацію.

Візьміть проміжний результат кожного виконання і збережіть їх у масиві для остаточної відповіді. Початкове число nне є частиною послідовності, також не є 0; приклади повинні зробити все трохи більш очевидним.

Розглянемо приклад, де 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]     

Ще один приклад 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]

Остаточний приклад n=11000:

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

Result: []

Це найнижчою кількістю виграшів.


2
Чи можуть бути надруковані результати у міру того, як відбудуться обчислення, або вони повинні побудувати масив?
FlipTack

Я припускаю, що застосовуються правила виводу за замовчуванням, тож ви можете вибрати формат виводу (масив, відображені цифри, розділені пробілами, ...)
Луїс Мендо

@ Flp.Tkc Я не буду обмежувати вихід, доки відображатимуться потрібні числа.
Чарівна урва восьминога

2
Лише зауважте, що "зворотний" число має сенс лише стосовно певної бази.
Девід Конрад

1
@ Sp3000 начебто; за винятком того, що вам потрібно приймати зворотні кожну ітерацію. Ви обчислюєте лише одне число за допомогою обчислення, а не два, а друге берете завжди, щоб воно було реверсом першого.
tomsmeding

Відповіді:



6

PowerShell v2 +, 89 байт

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

Ітеративне рішення. Тривалий, оскільки не існує простого способу повернути масив, тому ми впорядкуємо його та індексуємо його назад для зберігання $r. Потім псевдотермінал витягнути відповідний модуль і знову зберігати його $nдля наступного раунду. Однак якщо результат дорівнює нулю, це означає, що !($n...)буде $true, то ми exitзамість цього $n. Номери залишаються на конвеєрі і (неявно) повертаються як масив, але без інкапсуляції конвеєра або збереження результатів у змінну, за замовчуваннямWrite-Output вставляється новий рядок між.

Спробуйте в Інтернеті! (Так, мертвий серйозний.)
PowerShell зараз на TIO! Ви повинні дати йому другий або два, тому що PowerShell є звір запуску, але тепер ви, та ви , можете перевірити PowerShell код прямо в браузері!


Га, побий мене до цього і з тим же підходом. Приємно!
британіст

6

Perl, 43 38 + 1 = 39 байт

Біжи з -nпрапором

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

Спробуйте в Інтернеті! Включає два непусті приклади.

Пояснювальна схема

-n: Обгортає всю програму while(<>){ ... ;}. Це перетворює вище код в наступний рядок: while(<>){say while$_=($;=reverse)>$_?$;%$_:$_%$;}. Зауважте, крапка з комою була додана до трейлінгу $, тому тепер вона стає екземпляром змінної $;. В умовах whileциклу <>автоматично зчитує один рядок введення та зберігає його у $_змінній. Отже, тепер давайте розглянемо, що читає інтерпретатор всередині зовнішньої whileпетлі:

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

Оригінальний код, збережений для нащадків: 43 + 1 = 44 байти

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

$%>$_?$%%$_:$_%$%Ви вибрали $%змінну спеціально саме для цього рядка?
tomsmeding

Майже - я також зберігаю 1 байт, використовуючи не алфавітно-цифровий символ для останнього символу перед оператором while, тому мені не потрібно пробілу. Крім цього - досить багато, так
Габріель Бенамі

5

Pyth, 13 12 байт

t.u|%F_S,s_`

Завдяки @TheBikingViking

Спробуйте в Інтернеті: Демонстрація

Мій старий код:

W
W=Q%F_S,s_`

Спробуйте в Інтернеті: Демонстрація

Пояснення:

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 байт: t.u|%F_S,s_<backtick>. Тест
TheBikingViking

1
@TheBikingViking Спасибі, це дуже розумно.
Якубе

4

Желе , 15 14 13 байт

,ṚḌṢṚ%/
ÇÇпḊ

TryItOnline

Як?

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

Желе , 13 12 байт

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

Це монодійна посилання / функція, яка друкує на STDOUT.

Спробуйте в Інтернеті!

Як це працює

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

Для чого нижній колонтитул? Якщо вилучений код, схоже, виводиться кінцевий 0
Луїс Мендо

Це правильно. 0 є повертається значенням функції, яку інтерпретатор друкує , якщо він не відкидали. Згідно з цією мета-дискусією , це дозволено.
Денніс

4

Пітон 2, 92 87 81 73 61 байт

Рекурсивне рішення:

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

Спробуйте в Інтернеті

Ітеративне рішення: (також 61 байт )

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

Спробуйте в Інтернеті


Ітераційне рішення, яке я вам дав, - це насправді 59 байт, але я не впевнений, чи він дійсний, оскільки він друкує введення. Якщо це так, то ви можете пограти в 2 байти, просто зробивши це while n:. В іншому випадку ви можете зробити це з 61 байтом .
FlipTack

3

MATL , 16 байт

`tVPUhSPZ}\tt]xx

Спробуйте в Інтернеті!

Пояснення

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

Пакет, 140 байт

@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

Приймає вхід на STDIN і виводить послідовність на окремі рядки. Batch має умовні висловлювання (які є дещо дослідними), але немає умовних виразів, тому простіше (незважаючи на те, що потрібно цитувати %s), обчислити r%n%r(що дорівнює r%nif n<rабо нулю if n>r) і n%r%n(що дорівнює n%rif n>rабо zero if n<r) та додати їх разом.


2

Математика, 68 байт

Дякую Грегу Мартіну за те, що він запропонував використовувати, FixedPointListа не NestWhileList:

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

Найкоротший, з якого я міг отримати своє оригінальне рішення, - FixedPointListце 73 байти:

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

1
Зауважте, що у вас не зовсім правильна умова завершення (спробуйте приклад прикладу 11000). Ви можете обійти це, перейшовши на техніку, описану в останньому абзаці. Але я не бачу, як позбутися Restабо Mostтаким чином. З іншого боку, FixedPointList[ Mod[(r = IntegerReverse@#)~Max~#, r~Min~#] &, #][[2 ;; -4]] &після видалення пробілів лише 68 байт (викидає пару помилок, nbd).
Грег Мартін

Я якось переконав себе, що проміжки на зразок {a,b,c,d}[[2;;-4]]дадуть помилку, а не порожній список (я, мабуть, скористався комою, а не ;;). Навчився чогось.
ngenisis

Ви можете позбутися цілого мінімуму / максимуму бізнесу Sort:FixedPointList[-Mod@@Sort@-{#,IntegerReverse@#}&,#][[2;;-4]]&
Мартін Ендер

1

JavaScript, 72 70 байт

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}

Відредаговано:

-2 байти : Оператор розповсюдження чекає конкатенації рядків.


1

R, 126 117 байт

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

На жаль, перевернути число ( as.double(paste(rev(el(strsplit(c(x,""),""))),collapse="")))) досить багатослівно. Відпочити досить легко. Використовує sortдля опосередкованої перевірки, що вище.

Решта проста, вона продовжує циклічно доти x=0і друкує всі кроки.


1

C, 87 байт

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є тимчасовим для реверсування. Внутрішня петля зміщує r1 цифру вліво і додає останню цифру, tпоки вона не буде вичерпана. Вихід відбувається після першої ітерації, і лише якщо вона не дорівнює нулю, щоб запобігти відображенню першого та останнього елемента.

Безголовка та використання:

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

Математика, 64 байти

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

Вищевказаний код являє собою чисту функцію, яка займає один вхід і повертає послідовність кузнецов. Дійсно красива річ у математиці полягає в тому, що ви можете наносити шар на шар чистих функцій ... Дозвольте мені пояснити код;)

Кожен член у самій послідовності обчислюється за допомогою наведеної нижче функції, яка займає один вхід і повертає наступний доданок.

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

Код IntegerReverse@#просто генерує r, зворотне значення. Код #2~If[#<=#2,Mod,#0]~#&- це функція, яка займає два входи і або працює мод, або повертає входи та повторює виклик. Інший спосіб його написання є If[#<=#2, Mod, #0][#2, #]&, або він може бути записаний як звичайна функція, як це:k[a_, b_] := If[a <= b, Mod, k][b, a]


0

Ракетка 180 байт

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

Безумовно:

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

Тестування:

(f 32452345)
(f 12345678)

Вихід:

'(21873078 21418578 1907100 9999)
'(1234575 816021 92313 29655 26037 20988 4950 198 99)
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.