Đảo ngược Palindrom-Bổ sung


19

Đảo ngược Palindrom-Bổ sung

Quá trình Reversal-Addition là nơi một số được thêm vào đảo ngược cho đến khi số được tạo là một bảng màu. Ví dụ: nếu chúng tôi bắt đầu với 68, quy trình sẽ là:

68 + 86 => 154 + 451 => 605 + 506 => 1111

Như bạn có thể thấy, điều này đã mất 3 bổ sung để có được một số palindromic. Nếu chúng ta bắt đầu 89, chúng ta sẽ cần 24 bước (bạn có thể thấy sự cố ở đây ).

Kỷ lục thế giới về hầu hết các bước được thực hiện trước khi đạt được một bảng màu là 261, xảy ra cho số 1186060307891929990, tạo ra một số lớn hơn 10 118 . Tuy nhiên, đã có khá nhiều con số mà chúng ta không thể có được một bảng màu. Chúng được gọi là số Lychrel .

Vì chúng tôi đang làm việc tại cơ sở 10, chúng tôi thực sự chỉ có thể gọi họ là ứng cử viên, bởi vì không có bằng chứng nào cho thấy những con số này không bao giờ đạt đến một bảng màu. Ví dụ, ứng cử viên Lychrel cơ sở 10 nhỏ nhất là 196 và đã trải qua hơn một tỷ lần lặp. Nếu palindrom tồn tại, nó lớn hơn 10 10 8.77 . Để so sánh, nếu nhiều số 1 được ghi trên các nguyên tử, chúng ta sẽ cần 2.26772 × 10 588843575 các nguyên tử có giá trị để viết ra, giả sử nó tồn tại.

Nhiệm vụ của bạn

Tạo một chương trình hoặc hàm lấy đầu vào số nguyên và trả về hoặc in số bước cần thiết để đạt được một bảng màu. Bạn sẽ không bắt buộc phải đối phó với các ứng cử viên Lychrel (tức là chương trình của bạn, khi được cung cấp một ứng cử viên Lychrel, được phép ném lỗi hoặc chạy mãi mãi).

Các trường hợp thử nghiệm:

                  f(0) => 0
                 f(11) => 0
                 f(89) => 24
                f(286) => 23
          f(196196871) => 45
         f(1005499526) => 109
f(1186060307891929990) => 261

Quy tắc

  1. Không có sơ hở tiêu chuẩn.

Tiền thưởng

  1. Nếu bạn in ra từng bước bổ sung, được định dạng n + rev(n) = m, bạn có thể nhân số điểm của mình với 0,75 . Các khoản tiền nên in ra trước số bước.
  2. Nếu mã của bạn có thể phát hiện nếu một số là ứng cử viên Lychrel, bạn có thể nhân số điểm của mình với 0,85 . Trong trường hợp này, đủ để giả sử bất cứ điều gì mất hơn 261 lần lặp là một ứng cử viên Lychrel. Không trả về bất cứ điều gì, hoặc bất cứ điều gì không phải là một số có thể bị nhầm lẫn với một câu trả lời đúng (vv: bất kỳ chuỗi hoặc một số không nằm trong phạm vi 0-261). Bất kỳ lỗi nào không được tính là đầu ra hợp lệ (ví dụ vượt quá độ sâu đệ quy tối đa) và không thể được sử dụng trong phát hiện.
  3. Nếu bạn hoàn thành cả hai phần thưởng, nhân với 0,6 .

Đây là , vì vậy số byte ít nhất sẽ thắng.


Đoạn mã này hiển thị một giải pháp ví dụ trong Python 3 với cả hai phần thưởng.

def do(n,c=0,s=''):
  m = str(n)
  o = m[::-1]
  if c > 261:
    return "Lychrel candidate"
  if m == o:
    print(s)
    return c
  else:
    d = int(m)+int(o)
    s+="%s + %s = %s"%(m,o,str(d))
    return do(d,c+1,s)


1
*0.6tiền thưởng trên đầu trang của những người khác? Hay chỉ là vậy?
Maltysen

@Maltysen Chỉ là 0,6.
Kade

Khi in ra số tiền chúng ta nên in 10 + 01 = 11hoặc 10 + 1 = 11hoặc là nó lên với chúng ta?
Martin Ender

3
Đối với máy dò vải, tôi có thể in ra 262không?
Maltysen

Câu trả lời:


8

Bình thường, 12 byte

f_I`~+Qs_`Q0

Dùng thử trực tuyến: Trình diễn hoặc thử nghiệm khai thác

Điều này sử dụng một tính năng khá mới (chỉ 17 giờ).

Giải trình

               implicit: Q = input number
f          0   repeat the following expression until it 
               evaluates to true and return the number of steps
         `Q       convert Q to string
        _         reverse the digits
       s          convert to int
     +Q           add Q
    ~             assign the result to Q
                  (this returns the old value of Q)
   `              convert the old value of Q to a string
 _I               and check if it's invariant under the operation reverse

chỉnh sửa:

Thay đổi mã một chút. Phiên bản cũ là

fqKs_`Q~+QK0

Cùng một số byte, nhưng cái mới thì mát hơn.


Tiền thưởng với số điểm 12. Chúc may mắn!
Dennis

@Dennis Quyền của bạn. Đó là một ý định vô lý. Cái tốt nhất tôi có là 13.6 sử dụng phát hiện Lychrel.
Jakube

14

Con trăn, 51

def f(n):r=int(str(n)[::-1]);return n-r and-~f(n+r)

Đối với Python 2, backticks không thể thay thế str()vì được Lgắn với longchữ.

Đây là phiên bản thay thế có điểm 64 * 0.85 = 54.4 :

def f(n,c=262):r=int(str(n)[::-1]);return c*(n-r)and-~f(n+r,c-1)

Và một phiên bản thay thế cho Python 3 với số điểm 88 * 0,6 = 52,8 :

def f(n,c=262):r=int(str(n)[::-1]);return c*(n-r)and-~f(n+r,print(n,'+',r,'=',n+r)or~-c)

1
Đây chỉ là điên rồ .. công việc tốt đẹp!
Kade

6

CJam, 23 22 20,4 byte

ri{__sW%i+}261*]{s_W%=}#

Mã dài 24 byte và in -1 cho các ứng cử viên Lychrel.

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

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

ri                       e# Read an integer from STDIN.
  {       }261*          e# Do the following 261 times:
   __                    e#   Push two copies of the integer on the stack.
     sW%i                e#   Cast to string, reverse and cast back to integer.
         +               e#   Add the copy and the reversed copy of the integer.
               ]         e# Wrap all 262 results in an array.
                {     }# e# Push the index of the first element such that:
                 s       e#   The string representation equals...
                  _W%=   e#   the reversed string representation.

Nếu {}#thành công, chỉ số cũng là số bước. Mặt khác, nếu mảng không chứa một bảng màu, {}#sẽ đẩy -1 .


5

Java, 200 * 0,6 = 120

import java.math.*;int f(BigInteger a){int s=-1;for(String b,c;(b=a+"").equals(c=new StringBuffer(b).reverse()+"")!=s++<999;)System.out.println(b+" + "+c+" = "+(a=a.add(new BigInteger(c))));return s;}

Đây là một vòng lặp đơn giản chỉ thực hiện những gì nó nói trên hộp, nhưng với một số golf được thêm vào. Trả lại 1000cho các ứng cử viên Lychrel để nhận tiền thưởng phát hiện. Hóa ra tôi đã có thể in không quá nhiều ký tự (ít nhất là cho Java) và cũng nhận được phần thưởng đó. Điều tốt nhất tôi có thể làm mà không cần mã thưởng là 156, vì vậy nó rất xứng đáng.

Với một số ngắt dòng:

import java.math.*;
int f(BigInteger a){
    int s=-1;
    for(String b,c;(b=a+"").equals(c=new StringBuffer(b).reverse()+"")!=s++<999;)
        System.out.println(b+" + "+c+" = "+(a=a.add(new BigInteger(c))));
    return s;
}

Câu trả lời cũ: 171 * 0,85 = 145,35 byte

import java.math.*;int f(BigInteger a){int s=-1;for(String b,c;(b=a+"").equals(c=new StringBuffer(b).reverse()+"")!=s++<262;)a=a.add(new BigInteger(c));return s>261?-1:s;}


Tôi đoán bạn vẫn làm việc này trong khi nó vẫn ở trong hộp cát: P Tôi đang suy nghĩ lại về số tiền thưởng, vì tôi nhận ra ngay cả trong Python (một ngôn ngữ tương đối súc tích so với C # / Java), phần thưởng không giúp ích được gì. Tôi nghĩ rằng tôi sẽ làm cho nó liên quan đến độ dài của chương trình để các ngôn ngữ chơi gôn không kết thúc với số điểm <10 byte.
Kade

Tôi đã cập nhật các quy tắc thưởng, vì vậy điểm mới của bạn là 145,35 :)
Kade

Lưu một byte, xóa dấu chấm phẩy ở cuối định nghĩa, không bắt buộc, vì vậy sau đós++<999
Christopher Wirt

@ChristopherWirt Trong trình biên dịch / phiên bản nào? Của tôi cho một lỗi cú pháp mà không có nó.
Geobits

5

Ruby, (80 + 2) * 0,6 = ~ 49,2

Có cờ -nl, chạy

p (0..261).find{$_[b=$_.reverse]||puts($_+' + '+b+' = '+$_="#{$_.to_i+b.to_i}")}

Đầu ra trông như

 $ ruby -nl lychrel.rb 
89
89 + 98 = 187
187 + 781 = 968
968 + 869 = 1837
1837 + 7381 = 9218
9218 + 8129 = 17347
17347 + 74371 = 91718
91718 + 81719 = 173437
173437 + 734371 = 907808
907808 + 808709 = 1716517
1716517 + 7156171 = 8872688
8872688 + 8862788 = 17735476
17735476 + 67453771 = 85189247
85189247 + 74298158 = 159487405
159487405 + 504784951 = 664272356
664272356 + 653272466 = 1317544822
1317544822 + 2284457131 = 3602001953
3602001953 + 3591002063 = 7193004016
7193004016 + 6104003917 = 13297007933
13297007933 + 33970079231 = 47267087164
47267087164 + 46178076274 = 93445163438
93445163438 + 83436154439 = 176881317877
176881317877 + 778713188671 = 955594506548
955594506548 + 845605495559 = 1801200002107
1801200002107 + 7012000021081 = 8813200023188
24

Nếu được cho 196, nó sẽ in 261 bước bổ sung đầu tiên và sau đó nil.

Không có gì quá khó khăn ở đây. Chúng tôi kiểm tra xem $_(được khởi tạo cho đầu vào) có chứa đảo ngược hay không, điều này chỉ có thể nếu chúng bằng nhau vì chúng có cùng kích thước. Nếu đúng như vậy, chúng tôi sẽ in số bước và thoát, nếu không, chúng tôi sẽ hiển thị và thực hiện bước bổ sung, lưu trữ giá trị mới trong $_(Tôi không may chỉ evallà chuỗi tôi đang hiển thị vì nó diễn giải một số đảo ngược có dấu 0 như một bát phân theo nghĩa đen). putstrả về một giá trị falsey để vòng lặp tiếp tục.


" + #{b} = "tiết kiệm một byte.
Mitch Schwartz

Và có vẻ như trong các quy tắc sẽ bỏ qua -lnếu chúng ta đặt số vào một tệp mà không có dòng mới và đặt nó vào?
Mitch Schwartz


4

K, 25 byte

#1_{~x~|x}{$. x,"+",|x}\$

Không thanh lịch lắm. Dạng tổng thể ( {monad 1}{monad 2}\x) tương đương với K của một vòng lặp "while" chung, trong đó đơn vị đầu tiên là điều kiện tạm dừng và lần thứ hai là một hàm lặp được áp dụng cho đối số x. Đơn nguyên đầu tiên ( {~x~|x}) là sự phủ định của cụm từ "is xa palindrom" cổ điển. Đơn vị thứ hai nối với nhau một chuỗi đại diện cho x cộng với ngược lại của x, đánh giá nó và sau đó đưa kết quả trở lại thành một chuỗi với $.

Một mẫu chạy cho thấy kết quả trung gian:

  {~x~|x}{$. x,"+",|x}\$68
("68"
 "154"
 "605"
 "1111")

Làm đầu ra được định dạng theo yêu cầu cho phần thưởng sẽ rất vụng về và thêm một lượng mã đáng kể.


4

CJam, 23 byte

Wl{\)\__W%_@#\i@i+s\}g;

Vẫn chỉ còn vài ngày nữa để đến với CJam, vì vậy tôi khá vui khi được ở cùng tầm với một số ưu điểm. :) Tôi đã sử dụng thủ thuật so sánh chuỗi của Martin mà anh ấy cũng đã đăng trong gợi ý của CJam. Tôi cũng lén nhìn vào giải pháp của Dennis để tìm ra cách đảo ngược chuỗi.

Giải trình:

W    Initialize counter, will keep this at bottom of stack.
     Start counting at -1 because the counter will be incremented in the
     last pass through the loop, when the palindrome is detected.
l    Get input.
{    Start block of while loop.
\)\  Increment counter. Need to swap before/after because it's one below top of stack.
__   Copy current value twice. Need 3 copies in total:
       * one for reversal
       * one for comparison
       * one for addition with reverse
W%   Reverse value.
_    Copy the reverse value once because we need 2 copies:
       * one for comparison
       * one for addition with original value
@    Rotate one copy of original value to top.
#    Test for non-equality with reverse, using Martin's trick.
\i   Swap reverse value to top, and convert it to int.
@i   Rotate remaining copy of original value to top, and convert it to int.
+s   Add the values, and convert result to string.
\    Swap, so that comparison result is at top of stack for while loop test.
}g   End of while loop.
;    Current value sits at top of stack. Pop it, leaving only counter.

Kiểm tra trực tuyến


4

Julia, 129 120 byte * 0,6 = 72

i->(i=big(i);n=0;d=digits;while d(i)!=reverse(d(i))&&n<262 t=BigInt(join(d(i)));println(i," + ",t," = ",i+=t);n+=1end;n)

Điều này tạo ra một hàm không tên, lấy một số nguyên làm đầu vào và trả về một số nguyên, trong khi in mỗi bước. Các ứng cử viên của Lychrel có giá trị trả về là 262. Để gọi nó, hãy đặt tên cho nó, vd f=i->....

Lưu ý rằng bỏ qua mã chỉ liên quan đến tiền thưởng, giải pháp này sẽ là 84 byte.

Ungolfed + giải thích:

function f(i)
    # Convert the input to a big integer
    i = big(i)

    # Initialize a step counter to 0
    n = 0

    # While the number is not a palindrome and we haven't exceeded 261 steps...
    while digits(i) != reverse(digits(i)) && n < 262

        # Get the reverse of the integer
        # Note that we aren't using reverse(); this is because digits()
        # returns an array of the digits in reverse order.
        t = BigInt(join(digits(i)))

        # Print the step and increment i
        println(i, " + ", t, " = ", i += t)

        # Count the step
        n += 1
    end

    # Return the number of steps or 262 for Lychrel candidates
    n
end

Ví dụ:

julia> f(286)
286 + 682 = 968
968 + 869 = 1837
1837 + 7381 = 9218
9218 + 8129 = 17347
17347 + 74371 = 91718
91718 + 81719 = 173437
173437 + 734371 = 907808
907808 + 808709 = 1716517
1716517 + 7156171 = 8872688
8872688 + 8862788 = 17735476
17735476 + 67453771 = 85189247
85189247 + 74298158 = 159487405
159487405 + 504784951 = 664272356
664272356 + 653272466 = 1317544822
1317544822 + 2284457131 = 3602001953
3602001953 + 3591002063 = 7193004016
7193004016 + 6104003917 = 13297007933
13297007933 + 33970079231 = 47267087164
47267087164 + 46178076274 = 93445163438
93445163438 + 83436154439 = 176881317877
176881317877 + 778713188671 = 955594506548
955594506548 + 845605495559 = 1801200002107
1801200002107 + 7012000021081 = 8813200023188
23

julia> f(1186060307891929990)
(steps omitted)
261

julia> f(196)
(steps omitted)
262

julia> f(11)
0

Đã lưu 2 byte nhờ Geobits!


4

CJam, 24 byte

0q{__W%#}{_W%~\~+s\)\}w;

Kiểm tra nó ở đây.

Giải trình

0q     e# Push a zero (the counter) and read input.
{      e# While this block leaves something truthy on the stack...
  __   e#   Make two copies of the current number (as a string).
  W%   e#   Reverse the second copy.
  #    e#   Check that they are not equal.
}{     e# ... run this block.
  _W%  e#   Make a copy of the current number and reverse it.
  ~\~  e#   Evaluate both N and its reverse.
  +s   e#   Add them and turn the sum into a string.
  \)\  e#   Pull up the counter, increment it, and push it back down again.
}w
;      e# Discard the palindrome to leave the counter on the stack.

Để biết thêm thông tin về lý do tại sao #có thể được sử dụng để kiểm tra bất đẳng thức chuỗi, xem mẹo này .


Không thấy câu trả lời của bạn trước khi đăng. Đó là một cách sử dụng thông minh #.
Dennis

2

Haskell, 66 53 byte

r=reverse.show
f x|show x==r x=0|1<2=1+f(x+read(r x))

Ví dụ sử dụng:

*Main> map f [0,11,89,286,196196871,1005499526,1186060307891929990]
[0,0,24,23,45,109,261]

Tôi chưa bao giờ sử dụng Haskell trước đây, nhưng bạn có thể làm được r=reverse xkhông? Điều đó sẽ thay đổi dòng thứ hai của bạn thành f x|x==r=0|1<2=1+f(show$read x+read(r))và lưu 2 byte.
Kade

@ Vioz-: Không, điều đó là không thể, vì xsẽ không nằm trong phạm vi. Tuy nhiên, f x|x==r=0 .... read(r)) where r=reverse xsẽ làm việc, nhưng nó lâu hơn.
nimi

2

Clojure, 94 byte

(fn[x](#(let[r(bigint(apply str(reverse(str %1))))] (if(= %1 r)%2(recur(+ %1 r)(inc %2))))x 0))

Đây là lần đầu tiên tôi thử viết mã golf, vì vậy xin vui lòng cho tôi biết nếu tôi làm gì sai.

Với một số không gian:

(fn [x]
(#(let [r (bigint (apply str (reverse (str %1))))]
  (if (= %1 r) %2 (recur (+ %1 r) (inc %2)))) x 0))

Đệ quy đơn giản của hàm bên trong. Nó có hai đối số, số nguyên %1và một chỉ mục %2. Nếu %1là một bảng màu, chỉ mục được trả về. Mặt khác, hàm gọi chính nó bằng tổng và chỉ số tăng. Hàm ngoài khởi tạo chỉ mục bằng không.

Một ví dụ:

repl=> ((fn[x](#(let[r(bigint(apply str(reverse(str %1))))](if(= %1 r)%2(recur(+ %1 r)(inc %2))))x 0)) 1186060307891929990)
261

1

Boost.Build, 304 byte

Không thực sự là một ngôn ngữ. Vẫn ngầu.

import sequence ;
import regex ;
rule r ( n ) {
m = "([0-9]?)" ;
return [ sequence.join [ sequence.reverse [ regex.match "$(m)$(m)$(m)$(m)$(m)$(m)$(m)$(m)$(m)" : $(n) ] ] : "" ] ;
}
rule x ( n ) {
i = 0 ;
while $(n) != [ r $(n) ] {
n = [ CALC $(n) + [ r $(n) ] ] ;
i = [ CALC $(i) + 1 ] ;
}
echo $(i) ;
}

Khá đơn giản, khác với hack dựa trên regex phức tạp mà tôi đã sử dụng để đảo ngược chuỗi.


1

Hồng ngọc, 44

f=->n{n==(r=n.to_s.reverse.to_i)?0:f[n+r]+1}

Cần Ruby 1.9 hoặc cao hơn cho ->cú pháp lambda.

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.