Trình tự của Kuznetsov


18

Trình tự của Kuznetsov

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

Cho bất kỳ số nào n > 0, hãy rbiểu diễn đảo ngược của số n. Lặp lại cho đến khi kết quả cuối cùng bằng 0, chuyển kết quả của mỗi lần lặp lại vào hàm bằng cách sử dụng đệ quy hoặc phương pháp bạn chọn bằng cách thực hiện thao tác bên dưới:

  • Nếu r > ncho lần lặp đó kết quả là r % n.
  • Nếu n > rcho lần lặp đó kết quả là n % r.
  • Nếu n % r = 0hoặc r % n = 0, bạn chấm dứt lặp đi lặp lại.

Lấy kết quả trung gian của mỗi lần thực hiện và lưu trữ chúng trong một mảng cho câu trả lời cuối cùng. Số ban đầu nkhông phải là một phần của chuỗi, cũng không phải là 0; các ví dụ sẽ làm cho mọi thứ rõ ràng hơn một chút.

Hãy đi qua một ví dụ 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]     

Một ví dụ khác 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]

Một ví dụ cuối cùng n=11000:

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

Result: []

Đây là chiến thắng đếm byte thấp nhất trong .


2
Kết quả có thể được in khi tính toán xảy ra hay nó phải xây dựng một mảng?
FlipTack

Tôi giả sử áp dụng quy tắc đầu ra mặc định, vì vậy bạn có thể chọn formart đầu ra (mảng, số được hiển thị cách nhau bởi khoảng trắng, ...)
Luis Mendo

@ Flp.Tkc Tôi sẽ không hạn chế đầu ra, miễn là số lượng yêu cầu được hiển thị.
Bạch tuộc ma thuật Urn

2
Chỉ cần lưu ý rằng 'đảo ngược' của một số chỉ có ý nghĩa đối với một cơ sở cụ thể.
David Conrad

1
@ Sp3000 loại; ngoại trừ việc bạn cần thực hiện ngược lại mỗi lần lặp. Bạn chỉ xâu một số thông qua phép tính, không phải hai và lấy số thứ hai luôn luôn là số ngược của số đầu tiên.
tomsmeding

Câu trả lời:



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}

Giải pháp lặp lại. Dài dòng vì không có cách dễ dàng để đảo ngược một mảng, vì vậy chúng tôi xâu chuỗi nó và lập chỉ mục ngược lại để lưu trữ vào $r. Sau đó, một giả ba để rút modulo thích hợp và lưu trữ lại $ncho vòng tiếp theo. Tuy nhiên, nếu kết quả bằng không, điều đó có nghĩa là !($n...)sẽ $true, vì vậy chúng tôi exitthay vì $n. Các số được để lại trên đường ống và (hoàn toàn) được trả về dưới dạng một mảng, nhưng không có đường ống đóng gói hoặc lưu kết quả vào một biến, mặc định sẽ đặt Write-Outputmột dòng mới giữa.

Hãy thử trực tuyến! (Vâng, đã chết nghiêm trọng.)
PowerShell hiện đã có trên TIO! Bạn phải cho nó một hoặc hai giây, vì PowerShell là một con thú để khởi động, nhưng bây giờ, bạn, có bạn , có thể xác minh mã PowerShell ngay trong trình duyệt của bạn!


Gah, đánh bại tôi với nó và với cách tiếp cận tương tự. Đẹp!
briantist

6

Perl, 43 38 + 1 = 39 byte

Chạy với -ncờ

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

Hãy thử trực tuyến! Bao gồm hai ví dụ không trống.

Biểu đồ giải thích

-n: Kết thúc toàn bộ chương trình trong while(<>){ ... ;}. Điều này biến mã trên thành dòng sau : while(<>){say while$_=($;=reverse)>$_?$;%$_:$_%$;}. Lưu ý, một dấu chấm phẩy đã được thêm vào dấu $, vì vậy bây giờ nó trở thành một thể hiện của biến $;. Trong điều kiện của một whilevòng lặp, <>tự động đọc một dòng đầu vào và lưu nó trong $_biến. Vì vậy, bây giờ hãy xem những gì trình thông dịch đọc bên trong whilevòng lặp bên ngoài :

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

Mã gốc, được lưu cho hậu thế: 43 + 1 = 44 byte

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

$%>$_?$%%$_:$_%$%Bạn đã chọn $%biến trên mục đích chỉ cho dòng này?
tomsmeding

Hầu như - Tôi cũng tiết kiệm 1 byte bằng cách sử dụng ký tự không phải chữ và số cho ký tự cuối cùng trước câu lệnh while, vì vậy tôi không cần khoảng trắng. Khác với điều đó - khá nhiều, vâng
Gabriel Benamy

5

Bình thường, 13 12 byte

t.u|%F_S,s_`

Cảm ơn @TheBikingViking.

Dùng thử trực tuyến: Trình diễn

Mã cũ của tôi:

W
W=Q%F_S,s_`

Dùng thử trực tuyến: Trình diễn

Giải trình:

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>. Kiểm tra
TheBikingViking

1
@TheBikingViking Cảm ơn, điều đó thực sự thông minh.
Jakube

4

Thạch , 15 14 13 byte

,ṚḌṢṚ%/
ÇÇпḊ

Dùng thử

Làm sao?

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

Thạch , 13 12 byte

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

Đây là một liên kết / chức năng đơn âm in ra STDOUT.

Hãy thử trực tuyến!

Làm thế nào nó hoạt động

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

Chân trang để làm gì? Nếu bị xóa, mã dường như xuất ra dấu 0
Luis Mendo

Đúng rồi. Giá trị 0 là giá trị trả về của hàm, trình thông dịch sẽ in nếu nó không bị loại bỏ. Theo thảo luận meta này , điều đó được cho phép.
Dennis

4

Python 2, 92 87 81 73 61 byte

Giải pháp đệ quy:

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

Dùng thử trực tuyến

Giải pháp lặp: (cũng 61 byte )

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

Dùng thử trực tuyến


Giải pháp lặp mà tôi đã cung cấp cho bạn thực sự là 59 byte, nhưng tôi không chắc liệu nó có hợp lệ không vì nó in đầu vào. Nếu đúng như vậy, thì bạn có thể chơi golf 2 byte chỉ bằng cách thực hiện while n:. Nếu không, bạn có thể làm điều đó với 61 byte .
FlipTack

3

MATL , 16 byte

`tVPUhSPZ}\tt]xx

Hãy thử trực tuyến!

Giải trình

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

Hàng loạt, 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

Lấy đầu vào trên STDIN và xuất chuỗi trên các dòng riêng biệt. Batch có các câu lệnh có điều kiện (có phần dài dòng) nhưng không có biểu thức điều kiện nên dễ dàng hơn (mặc dù phải trích dẫn %s) để tính toán r%n%r(bằng với r%nif n<rhoặc zero if n>r) và n%r%n(bằng với n%rif n>rhoặc zero if n<r) và thêm Họ cùng nhau.


2

Toán học, 68 byte

Cảm ơn Greg Martin đã gợi ý tôi sử dụng FixedPointListchứ không phải NestWhileList:

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

Thời gian ngắn nhất tôi có thể nhận được giải pháp ban đầu của mình FixedPointListlà 73 byte:

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

1
Lưu ý rằng bạn không có điều kiện kết thúc hoàn toàn đúng (thử đầu vào ví dụ 11000). Bạn có thể khắc phục điều này bằng cách chuyển sang kỹ thuật được mô tả trong đoạn cuối của bạn. Nhưng tôi không thấy làm thế nào để thoát khỏi Resthoặc Mosttheo cách này. Mặt khác, FixedPointList[ Mod[(r = IntegerReverse@#)~Max~#, r~Min~#] &, #][[2 ;; -4]] &chỉ có 68 byte sau khi khoảng trắng bị xóa (ném một vài lỗi, nbd).
Greg Martin

Bằng cách nào đó tôi đã tự thuyết phục bản thân rằng các nhịp như {a,b,c,d}[[2;;-4]]sẽ gây ra lỗi thay vì danh sách trống (có lẽ tôi đã sử dụng dấu phẩy chứ không phải ;;). Đã học được điều gì đó.
ngenisis

Bạn có thể thoát khỏi toàn bộ doanh nghiệp tối thiểu / tối đa đó bằng Sort:FixedPointList[-Mod@@Sort@-{#,IntegerReverse@#}&,#][[2;;-4]]&
Martin Ender

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}

Đã chỉnh sửa:

-2 byte : Toán tử trải rộng chờ nối chuỗi.


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

Đáng buồn thay, đảo ngược một số ( as.double(paste(rev(el(strsplit(c(x,""),""))),collapse="")))) là khá dài dòng. Nghỉ ngơi là khá dễ dàng. Sử dụng sortđể gián tiếp kiểm tra cái nào cao hơn.

Phần còn lại rất đơn giản, nó cứ lặp đi lặp lại cho đến khi x=0và in tất cả các bước.


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

tlà tạm thời để đảo ngược. Vòng lặp bên trong dịch chuyển r1 chữ số sang trái và thêm chữ số cuối cùng tcho đến khi hết. Đầu ra là sau lần lặp đầu tiên và chỉ khi nó khác không để ngăn mục đầu tiên và mục cuối cùng được hiển thị.

Ungolfed và cách sử dụng:

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

Toán học, 64 byte

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

Đoạn mã trên biểu thị một hàm thuần nhận một đầu vào duy nhất và trả về chuỗi kuznetsovs. Điều thực sự hay về mathicala là bạn có thể đặt lớp trên lớp hàm thuần túy ... Cho phép tôi giải thích mã;)

Mỗi thuật ngữ trong chính chuỗi được tính với hàm bên dưới, sẽ lấy một đầu vào và trả về thuật ngữ tiếp theo.

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

IntegerReverse@#chỉ tạo r, giá trị đảo ngược. Mã #2~If[#<=#2,Mod,#0]~#&này là một hàm có hai đầu vào và thực hiện thao tác mod hoặc đảo ngược các đầu vào và gọi lại chính nó. Một cách viết khác là nó If[#<=#2, Mod, #0][#2, #]&, hoặc nó có thể được viết như một hàm thông thường như thế này:k[a_, b_] := If[a <= b, Mod, k][b, a]


0

Vợt 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)))))

Ung dung:

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

Kiểm tra:

(f 32452345)
(f 12345678)

Ouput:

'(21873078 21418578 1907100 9999)
'(1234575 816021 92313 29655 26037 20988 4950 198 99)
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.