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


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 вроде; за исключением того, что вам нужно делать обратное каждую итерацию. Вы вычисляете только одно число, а не два, и берете второе, чтобы всегда быть обратным первому.
Томсминг

Ответы:



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)

$%>$_?$%%$_:$_%$%Вы выбрали $%переменную специально для этой строки?
Томсминг

Почти - я также сохраняю 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

Python 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

PHP, 78 байт

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

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 имеет условные операторы (которые несколько многословны), но не содержит условных выражений, поэтому проще (несмотря на то, что нужно заключать в кавычки %) вычислить r%n%r(что равно r%nif n<rили ноль if n>r) и n%r%n(что равно n%rif n>rили ноль if n<r) и добавить их вместе.


2

Mathematica, 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 байта : оператор Spread ожидает объединения строк.


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до тех пор, пока она не будет исчерпана. Вывод идет после первой итерации и только если он ненулевой, чтобы предотвратить отображение первого и последнего элемента.

Ungolfed и использование:

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 байта

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

Приведенный выше код представляет собой чистую функцию, которая принимает один вход и возвращает последовательность Кузнецова. Действительно прекрасная вещь в Mathematica состоит в том, что вы можете наносить слой на слой чистых функций ... Позвольте мне объяснить код;)

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

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

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

Тестирование:

(f 32452345)
(f 12345678)

Ouput:

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