Đảo ngược và trừ


22

Mô tả thử thách

Hãy lấy một số nguyên dương n, đảo ngược các chữ số của nó để lấy rev(n)và nhận giá trị tuyệt đối của hiệu của hai số này: |n - rev(n)|(hoặc abs(n - rev(n))).

Thí dụ:

n = 5067 
rev(n) = 7605
|n - rev(n)| = |5067 - 7605| = |-2538| = 2538

Sau khi lặp lại thao tác này đủ nhiều lần, hầu hết các số sẽ trở thành 0(do đó chấm dứt vòng lặp) ...

5067 -> 2538 -> 5814 -> 1629 -> 7632 -> 5265 -> 360 -> 297 -> 495 -> 99 -> 0

... mặc dù một số số (như 1584) bị kẹt trong một vòng lặp vô hạn:

1584 -> 3267 -> 4356 -> 2178 -> 6534 -> 2178 -> 6534 -> 2178 -> 6534 -> ...
                        ^ infinite loop starts here

Công việc của bạn là xác định xem một số nguyên đã cho có bị kẹt trong một vòng lặp vô hạn hay không.

Mô tả đầu vào

Một số nguyên dương.

Mô tả đầu ra

Giá trị trung thực ( True, 1) nếu số bị kẹt trong một vòng lặp vô hạn False, 0nếu không thì giá trị giả ( , ).

Ghi chú

  • Số 0 triling nên được ommited. tức rev(5020) = 205.
  • Hãy nhớ rằng đây là , vì vậy hãy viết mã của bạn càng ngắn càng tốt!
  • Trình tự liên quan: A072140


Một lưu ý thú vị: có thể xây dựng một số nguyên dài tùy ý với chu kỳ lặp là 2, như được mô tả trong các nhận xét về A072141 . Phương pháp này giống hệt nhau cho các thời kỳ khác, như 12, 14, 17 và 22.
mbomb007

Câu trả lời:


18

Bình thường, 5 byte

4 byte nhờ FryAmTheEggman

uas_`

Bộ thử nghiệm.

Giá trị trung thực là một trong những số trong vòng lặp.

Giá trị falsey là 0.

Giải trình

uas_`      Input:Q
uas_`GGQ   Implicit filling of variables.

u      Q   Set G as Q: do this repeatedly until result seen before: Set G as
 a             the absolute difference of
     G             G
    `              convert to string
   _               reverse
  s                convert to integer
      G        and G

Sử dụng tốt các biến tự động điền!
FryAmTheEggman

1
* lạm dụng - - - - -
Leaky Nun

Làm thế nào nó hoạt động, cho một người không biết Pyth?
Gây tử vong vào

3
Làm thế nào là pyth rất ngắn nhưng vẫn trong phạm vi ASCII ._.
Hạ cấp

3
@Downgoat Vì là trăn.
Rò rỉ Nun

11

Toán học, 39 37 byte

Nest[Abs[#-IntegerReverse@#]&,#,#]<1&

Chỉ cần áp dụng nthời gian chuyển đổi ngược / trừ cho đầu vào nvà sau đó kiểm tra xem kết quả có 0. Không bao giờ có thể mất nhiều hơn 10ncác bước để đạt được một vòng lặp, bởi vì phép biến đổi không thể tăng số lượng chữ số và có ít hơn các 10nsố không có nhiều chữ số hơn n. Xem bằng chứng của Dennis để biết cách giảm ràng buộc này n.


10

Thạch , 6 5 byte

ṚḌạµ¡

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

Lý lịch

Điều này sử dụng giới hạn trên 10n của @ MartinEnder và các quan sát sau đây.

  1. 9 × 10 k - 1 số nguyên dương n với k chữ số.

  2. Sự khác biệt của một số và đảo ngược của nó luôn là bội số của 9 , vì vậy chỉ 10 k - 1 trong số chúng có thể xảy ra sau lần lặp đầu tiên.

  3. Trong các bội số, hơn 1/10 sẽ mất một chữ số trong lần lặp tiếp theo (đối với người bắt đầu, tất cả bắt đầu và kết thúc với cùng một chữ số, và gần gấp đôi nếu chữ số đầu tiên không phải là 1 cũng không phải là 9 ), vì vậy phải mất tối đa 9 × 10 k - 2 để vào một vòng lặp hoặc mất một chữ số.

  4. Áp dụng cùng một lý do cho số nguyên kết quả cuối cùng của k - 1 chữ số, v.v., phải mất tối đa 9 × 10 k - 2 + 9 × 10 k - 2 + Vòng ≤ 10 k - 1 ≤ n lần lặp để vào một vòng lặp hoặc đạt 0 .

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

ṚḌạµ¡  Main link. Argument: n

   µ¡  Iteratively apply the chain to the left n times.
Ṛ      Reverse n (casts to digits).
 Ḍ     Undecimal; convert from base 10 to integer.
  ạ    Take the absolute difference of the result and the argument.

11
Pyth đã đánh bại Jelly?
Rò rỉ Nun

3
Vâng, đó là một cà vạt.
Dennis

Đây không phải là byte.
mik

1
@mik Vui lòng nhấp vào liên kết byte trong tiêu đề.
Dennis

5

Oracle SQL 11.2, 136 byte

WITH v(n)AS(SELECT :1 FROM DUAL UNION ALL SELECT ABS(n-REVERSE(n||''))FROM v WHERE n>0)CYCLE n SET c TO 0 DEFAULT 1 SELECT MIN(c)FROM v;

Không chơi gôn

WITH v(n) AS
(
  SELECT :1 FROM DUAL
  UNION ALL
  SELECT ABS(n-REVERSE(n||''))FROM v WHERE n>0 
) CYCLE n SET c TO 0 DEFAULT 1
SELECT MIN(c)FROM v

5

APL, 26 ký tự

0∘{⍵∊⍺:×⍵⋄(⍺,⍵)∇|⍵-⍎⌽⍕⍵}

Chúng tôi sử dụng đối số bên trái làm công cụ tích lũy các giá trị mà chúng tôi đã thấy. Chúng tôi khởi tạo nó thành "0", đây là một trong hai điều kiện chấm dứt. Người bảo vệ ⍵∊⍺:×⍵được đọc: "là đối số đúng mà chúng ta đã thấy (và bao gồm số không)? Nếu vậy hãy trả về dấu của số, đó là 1 hoặc 0". Mặt khác, hãy lặp lại bằng cách gọi chính chúng ta với giá trị tuyệt đối của phép trừ sau khi đã đưa giá trị hiện tại vào đối số bên trái.


Một bản tóm tắt của giải pháp Mathicala của Martin Ender sẽ có tốc độ 21 ký tự :

 {×{|⍵-⍎⌽⍕⍵}⍣(10×⍵)⊣⍵}

Nó viết: "dấu hiệu của kết quả sau khi áp dụng 10n lần mong muốn" là gì?


4

Python 2, 50 byte

n=input()
exec'n=abs(n-int(`n`[::-1]));'*n
print n

Kiểm tra nó trên Ideone .

Lý lịch

Điều này sử dụng giới hạn trên 10n của @ MartinEnder và các quan sát sau đây.

  1. 9 × 10 k - 1 số nguyên dương n với k chữ số.

  2. Sự khác biệt của một số và đảo ngược của nó luôn là bội số của 9 , vì vậy chỉ 10 k - 1 trong số chúng có thể xảy ra sau lần lặp đầu tiên.

  3. Trong các bội số, hơn 1/10 sẽ mất một chữ số trong lần lặp tiếp theo (đối với người bắt đầu, tất cả bắt đầu và kết thúc với cùng một chữ số, và gần gấp đôi nếu chữ số đầu tiên không phải là 1 cũng không phải là 9 ), vì vậy phải mất tối đa 9 × 10 k - 2 để vào một vòng lặp hoặc mất một chữ số.

  4. Áp dụng cùng một lý do cho số nguyên kết quả cuối cùng của k - 1 chữ số, v.v., phải mất tối đa 9 × 10 k - 2 + 9 × 10 k - 2 + Vòng ≤ 10 k - 1 ≤ n lần lặp để vào một vòng lặp hoặc đạt 0 .



3

Python, 129 120 96 byte

Nếu một ngoại lệ bị bắt (thông thường ngoại lệ duy nhất có thể được ném với hàm này là RuntimeError, do đệ quy vô hạn), in 1. Mặt khác, in kết quả, 0.

def r(n):a=abs(n-int(str(n)[::-1]));return a and r(a)
try:print(r(int(input())))
except:print(1)

Cảm ơn @LeakyNun
Cảm ơn @shooqie


Đó chính thức là một sự lạm dụng (tốt đẹp) của đệ quy vô hạn.
Nữ tu bị rò rỉ

return a and rev(a)
Rò rỉ Nun

3
Không thể có được RuntimeError do đệ quy rất dài mà không nhất thiết phải là vô hạn?
Gây tử vong vào

a=[n-x,x-n][n>x]
Rò rỉ Nun

Bạn có thể rút ngắn nó một cách quyết liệt : def rev(n):a=abs(n-int(str(n)[::-1]));return a and rev(a). Ngoài ra, hãy đặt tên cho phương thức một cái gì đó ngắn (như rthay vì rev)
shooqie

3

Python, 101 98 byte

Thuật toán rùa và thỏ.

Truthy là bất kỳ giá trị trong vòng lặp, falsey là 0.

g=lambda n:abs(n-int(str(n)[::-1]))
def r(n):
    t=g(n);h=g(t)
    while t-h:h=g(g(h));t=g(t)
    return h

Nghĩa là nó!


3

Python 2, 85 84 83 byte

L=[]
def f(n,L=L):
    if n<1or n in L:print n<1
    else:L+=[n];f(abs(n-int(`n`[::-1])))

Một câu trả lời khác của Python. Nó thêm n vào danh sách cho mỗi lần lặp và nếu n đã có trong danh sách, nó sẽ xuất ra False. Nếu không, nó hoạt động xuống 0.

Cảm ơn @NonlinearFnut cho một byte.


1
Tôi tin rằng print n<1các tác phẩm (vì nluôn luôn không âm) và nó tiết kiệm một byte
NonlinearFbean

def f(n,L=[]):¶ if n<1or n in L:print n<1¶ else:f(abs(n-int(`n`[::-1])),L+[n])tiết kiệm 5 byte
Leaky Nun

3

05AB1E, 11 8 6 byte

DFÂï-Ä

Giải thích

DF          # input number of times do
  Â         # push current number and its reverse
   ï-       # convert reverse to int and subtract
     Ä      # absolute value
            # implicitly print after loop ends

Giá trị thật là một số từ vòng lặp.
Giá trị giả là 0.

Dùng thử trực tuyến

Sử dụng giới hạn trên được giải thích trong câu trả lời của Dennis 'Jelly

Đã lưu 2 byte nhờ @Adnan

Trong phiên bản 7.9 của 05AB1E, các giải pháp 5 byte sau hoạt động như được ghi nhận bởi @Adnan

DFÂ-Ä

Được rồi, đây là một chút của một golf kỳ lạ nhưng DFÂ-Ähoạt động trong phiên bản 7.9 nhưng không phải trong phiên bản hiện tại. Trong phiên bản hiện tại, bạn cần chuyển đổi nó thành int trước (như thế này DFÂï-Ä), nhưng bạn có thể sử dụng phiên bản 7.9 để tạo thành 5 byte: p.
Adnan

@Adnan Tôi không thể tin rằng tôi đã quên chức năng phân chia. Tôi sẽ giữ nguyên phiên bản hiện tại. Bạn có thể đăng 7.9 như một câu trả lời riêng nếu bạn muốn. Nếu không tôi sẽ đặt nó như một ghi chú.
Emigna

Tôi có lẽ sẽ không đăng nó, vì nó chỉ cách câu trả lời này 1 byte: p.
Adnan

1

Java 7, 161 byte

Điều này đòi hỏi một nhập khẩu nhưng tôi đã viết nó như là một chức năng. Mắng tôi trong các ý kiến ​​nếu một chương trình đầy đủ được ưa thích trong kịch bản này. Xuất ra 1 nếu có một vòng lặp vô hạn và 0 nếu giá trị về 0.

import java.util.*;int z(int a){int o,r,c=a;Set s=new HashSet();while(c!=0){for(r=0,o=c;o!=0;r=r*10+o%10,o/=10);c=Math.abs(c-r);if(!s.add(c))return 1;}return 0;}

Lưu ý rằng tôi đã thấy nhập khẩu và các chức năng được thực hiện trước đó. ví dụ
Chọc

1thật không?
Rò rỉ Nun

1
@LeakyNun 1 không được coi là trung thực trong java nhưng danh sách OP (Đúng, 1) và (Sai, 0) là đầu ra chấp nhận được.
Chọc

@LeakyNun Java thậm chí có ý nghĩa về sự thật hay giả?
Neil

@Neil Java có ý thức tận dụng các cơ hội hiệp đồng trong bối cảnh thị trường theo chiều dọc - đó là
con mèo

1

Brachylog , 49 32 23 byte

:10*N,?:N:{r:?-+.}itT'0

Trả về truecác vòng lặp vô hạn vàfalse khác.

Đây là một sự điều chỉnh không biết xấu hổ về thuật toán của Martin Ender.

Câu trả lời trước, 32 byte

g{tTr:T-+U(0!\;?:ImU;?:[U]c:1&)}

Giải thích về câu trả lời trước

g{                             } Call predicate with [Input] as input
  tT                             T is the last element of Input
    r:T-                         Subtract T from the reverse of T
        +U                       U is the absolute value of T
          (0!\                   If U is 0, return false
              ;                  Or
               ?:ImU             If U is in Input, return true
                    ;            Or
                     ?:[U]c:1&)  Recursive call with U concatenated to the Input

0

PowerShell v2 +, 94 byte

param($n)for($a=,0;){if(($n=[math]::Abs($n-(-join"$n"["$n".length..0])))-in$a){$n;exit}$a+=$n}

Đưa đầu vào $n, bắt đầu một forvòng lặp vô hạn , với $a=,0điều kiện ban đầu (điều này sử dụng toán tử dấu phẩy để đặt $athành một mảng của một phần tử, 0). Điều này$a là mảng các giá trị đã thấy của chúng tôi.

Mỗi vòng lặp chúng tôi kiểm tra một if. Điều kiện đầu tiên đặt giá trị tiếp theo của $nviệc sử dụng đảo ngược chuỗi và lệnh [math]::Absgọi .NET và kiểm tra xem giá trị đó đã được chưa -in $a. Nếu vậy, chúng tôi đầu ra $nexit . Mặt khác, chúng ta thêm giá trị đó vào mảng và tiếp tục vòng lặp.

Đầu ra 0cho các giá trị đầu vào trong đó nó không đi vào một vòng lặp vô hạn (là falsey trong PowerShell) và xuất ra giá trị mà vòng lặp gặp phải nếu không (số nguyên khác không là số thật). Ví dụ, đầu ra 2178cho đầu vào 1584.


0

Haskell, 65 byte

_#0=0
a#n|elem n a=1|1<2=(n:a)#abs(n-(read$reverse$show n))
([]#)

Trả về 0sai và 1đúng. Ví dụ sử dụng: ([]#) 1584->1 .

Cách tiếp cận rõ ràng: giữ một danh sách với tất cả các kết quả được nhìn thấy cho đến nay. Tính số tiếp theo cho đến khi 0hoặc trong danh sách.


0

JavaScript (ES6), 75 byte

f=(n,...a)=>a.includes(n=n<0?-n:n)?n:f([...n+``].reverse().join``-n,n,...a)

n<0?n=-n:nn*=n>0||-1cũng làm việc. Thuật toán có phần giống với câu trả lời PowerShell, mặc dù đây là một công thức đệ quy.


0

Ruby, 57 byte

->n,*h{h[n]=n=(n-"#{n}".reverse.to_i).abs until h[n];n>0}

Các mảng trống ban đầu htheo dõi các giá trị đạt được trước đó. Chúng tôi lặp lại số cho đến khi chúng tôi đạt được một giá trị trước đó, sau đó kiểm tra giá trị ở lần lặp cuối cùng. Vì 0 là chu kỳ của 1, nên nó sẽ là 0 nếu và chỉ khi không có chu kỳ lớn hơn. Tôi mất thêm 2 byte để chuyển đổi thành Boolean vì 0 là sự thật trong Ruby.


0

Perl 6  58 53 33  30 byte

sub {$/=%;$^a,{return ?1 if $/{$_}++;abs $_-.flip}...0;?0}
{$/=%;?($_,{last if $/{$_}++;abs $_-.flip}...0)[*-1]}
{?($_,{abs $_-.flip}...0)[10**$_]}

{?($_,{abs $_-.flip}...0)[$_]}

Giải trình:

{ # block lambda with implicit parameter $_

  # coerce the following to Bool
  # ( False for Nil or 0, True otherwise )
  ?

  (

    $_, # start a sequence with the input

    # block lambda with implicit parameter $_
    # subtracts the previous value in the sequence and its reverse
    # ( .flip is short for $_.flip where a term is expected )
    { abs $_ - .flip } 

    ... # repeat that lambda
    0   # until you get 0

  # get the element indexed with the block's input
  # may be 0, Nil, or a number that is part of a repeating sequence
  )[ $_ ]
}

(dựa vào quan sát trước đó rằng bạn chỉ cần thực hiện chuyển đổi này nhiều nlần)


0

Perl 5, 31 29 byte

perl -pe'for$x(1..$_){$_=abs$_-reverse}'

perl -pe'eval"\$_=abs\$_-reverse;"x$_'

Nó lặp lại n=|n-rev(n)|n lần, vì vậy đầu ra là 0 nếu không có vòng lặp,> 0 nếu không. Dennis đã chứng minh điều này là đủ.

Phiên bản mới sử dụng evalxlặp lại toán tử thay vì forvòng lặp.


Câu trả lời hay, và chào mừng bạn đến với PPCG! Lưu ý rằng cho Perl, tùy chọn dòng lệnh phải được bao gồm trong byte-count của bạn, vì vậy đây không phải là khá 30 byte.
admBorkBork

@TimmyD ok, +1 cho -ptùy chọn, -lkhông cần thiết cho một đầu vào
mik

0

Matlab, 89 84 byte

n=input('');z=n;while n
z=abs(z-str2num(fliplr(num2str(z))));n=[n z]*all(n~=z);end
z

Cách tiếp cận đơn giản - sắp xếp tất cả các số và kiểm tra nếu một số xuất hiện trước đó.

Giải trình

n=input('');z=n;  -- take input, initiate z
while n           -- n is said to be positive
z=abs(z-str2num(fliplr(num2str(z)))) -- calculate the "reverse and substract"
n=[n z]           -- put the value at the end of the vector
       *all(n~=z) -- make the n all zeroes if z is previously in the vector (break the loop)
end
z                 -- print z (0 when not entered loop, >0 otherwise)
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.