การเพิ่มกลับทาง Palindrome


19

การเพิ่มกลับทาง Palindrome

กระบวนการของการกลับรายการเพิ่มคือที่ที่มีการเพิ่มจำนวนลงในนั้นจะกลับหลังจนกว่าจำนวนที่สร้างขึ้นจะเป็นแบบสี ตัวอย่างเช่นถ้าเราเริ่มต้นด้วย 68 กระบวนการจะเป็น:

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

อย่างที่คุณเห็นสิ่งนี้ใช้เวลา 3 ส่วนเพื่อรับจำนวน palindromic ถ้าเราจะเริ่มต้นด้วย89เราจะต้องมี 24 ขั้นตอน (ซึ่งคุณสามารถดูรายละเอียดที่นี่ )

บันทึกสถิติโลกสำหรับขั้นตอนการดำเนินการมากที่สุดก่อนที่จะ palindrome จะมาถึงคือ 261 ซึ่งเกิดขึ้นสำหรับจำนวน1186060307891929990การผลิตจำนวนที่มีขนาดใหญ่กว่า 10 118 อย่างไรก็ตามมีตัวเลขไม่กี่ตัวที่เราไม่สามารถรับได้ เหล่านี้เรียกว่าหมายเลข Lychrel

เนื่องจากเราทำงานในฐาน 10 เราสามารถเรียกพวกเขาว่าผู้สมัครเพราะไม่มีข้อพิสูจน์ว่าตัวเลขเหล่านี้ไม่ถึง palindrome ตัวอย่างเช่นผู้สมัคร Lychrel -10 ที่มีขนาดเล็กที่สุดคือ 196 คนและผ่านการทำซ้ำกว่าพันล้านครั้ง ถ้า palindrome นั้นมีอยู่มันใหญ่กว่า 10 10 8.77มาก จากการเปรียบเทียบถ้า 1s จำนวนมากถูกจารึกไว้บนอะตอมเราจะต้องใช้ 2.26772 × 10 588843575จักรวาลที่มีค่าของอะตอมในการเขียนออกมาโดยสมมติว่ามันมีอยู่

งานของคุณ

สร้างโปรแกรมหรือฟังก์ชั่นที่รับอินพุตเป็นจำนวนเต็มและส่งคืนหรือพิมพ์จำนวนขั้นตอนที่จำเป็นในการเข้าถึง Palindrome คุณไม่จำเป็นต้องจัดการกับผู้สมัคร Lychrel (เช่นโปรแกรมของคุณเมื่อได้รับผู้สมัคร Lychrel ได้รับอนุญาตให้โยนข้อผิดพลาดหรือทำงานตลอดไป)

กรณีทดสอบ:

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

กฎระเบียบ

  1. ไม่มีช่องโหว่มาตรฐาน

โบนัส

  1. หากคุณพิมพ์ออกมาในแต่ละขั้นตอนนอกจากนี้ในรูปแบบที่n + rev(n) = mคุณอาจคูณคะแนนของคุณโดย0.75 จำนวนเงินควรพิมพ์ออกมาก่อนจำนวนขั้นตอน
  2. หากรหัสของคุณสามารถตรวจสอบได้หากมีจำนวนเป็นผู้สมัครที่ Lychrel คุณอาจคูณคะแนนของคุณโดย0.85 ในกรณีนี้มันเพียงพอที่จะสมมติว่ามีอะไรมากกว่า 261 iterations ซ้ำเป็นผู้สมัครลิ้นจี่ ไม่คืนค่าอะไรเลยหรืออะไรก็ตามที่ไม่ใช่ตัวเลขที่สามารถเข้าใจผิดว่าเป็นคำตอบที่ถูกต้อง (ฯลฯ : สตริงใด ๆ หรือตัวเลขที่ไม่อยู่ในช่วง 0-261) ข้อผิดพลาดใด ๆ จะไม่ถูกนับเป็นเอาท์พุทที่ถูกต้อง (เช่นความลึกการเรียกซ้ำสูงสุดเกิน) และไม่สามารถใช้ในการตรวจจับได้
  3. หากคุณเสร็จสมบูรณ์ทั้งโบนัสคูณด้วย0.6

นี่คือดังนั้นจำนวนไบต์ที่น้อยที่สุดจึงจะชนะ


ข้อมูลโค้ดนี้แสดงตัวอย่างโซลูชันใน Python 3 พร้อมทั้งโบนัส

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.6โบนัสที่ด้านบนของคนอื่น ๆ ? หรือเป็นเพียงแค่นั้น
Maltysen

@ Maltysen เพียงแค่ 0.6
Kade

เมื่อพิมพ์ผลรวมเราควรพิมพ์10 + 01 = 11หรือ10 + 1 = 11ขึ้นอยู่กับเรา
Martin Ender

3
สำหรับ lychrel detector ฉันสามารถพิมพ์ออกมาได้262หรือไม่?
Maltysen

คำตอบ:


8

Pyth, 12 ไบต์

f_I`~+Qs_`Q0

ลองใช้งานออนไลน์: การสาธิตหรือชุดทดสอบ

สิ่งนี้ใช้คุณสมบัติที่ค่อนข้างใหม่ (อายุเพียง 17 ชั่วโมง)

คำอธิบาย

               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

แก้ไข:

เปลี่ยนรหัสเล็กน้อย รุ่นเก่าคือ

fqKs_`Q~+QK0

นับไบต์เดียวกัน แต่อันใหม่จะเย็นกว่า


โบนัส 12 คะแนนโชคดี!
Dennis

@Dennis ของคุณถูกต้อง นั่นเป็นความตั้งใจที่ไร้สาระ สิ่งที่ดีที่สุดที่ฉันมีคือ 13.6 โดยใช้การตรวจจับลิ้นจี่
Jakube

14

Python 51

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

สำหรับ Python 2 backticks ไม่สามารถแทนที่ได้str()เนื่องจากไฟล์Lแนบกับlongตัวอักษร

นี่คือรุ่นอื่นที่มีคะแนน 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)

และรุ่นอื่นสำหรับPython 3 ที่มีคะแนน 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
นี่มันบ้ามาก ๆ งานดีมาก!
Kade

6

CJam, 23 22 20.4 ไบต์

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

รหัสมีความยาว 24 ไบต์และพิมพ์-1สำหรับผู้สมัคร Lychrel

ลองออนไลน์

มันทำงานอย่างไร

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.

หาก{}#สำเร็จดัชนีก็เป็นจำนวนขั้นตอนเช่นกัน หากในมืออื่น ๆ ที่อาเรย์ไม่ได้มีประโยคที่{}#จะผลักดัน-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;}

นี่คือการวนรอบแบบเรียบง่ายที่ทำสิ่งที่มันบอกไว้ในกล่อง แต่ด้วยการตีกอล์ฟ ส่งคืน1000ผู้สมัคร Lychrel เพื่อรับโบนัสการตรวจจับ ปรากฎว่าฉันสามารถพิมพ์ได้ไม่เกินไปสำหรับตัวละคร (สำหรับ Java อย่างน้อย) และขัดขวางโบนัสนั้นด้วย สิ่งที่ดีที่สุดที่ฉันสามารถทำได้โดยไม่มีรหัสโบนัสคือ 156 ดังนั้นมันจึงคุ้มค่า

ด้วยการขึ้นบรรทัดใหม่:

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

คำตอบเก่า: 171 * 0.85 = 145.35 ไบต์

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


ฉันเดาว่าคุณทำงานนี้ในขณะที่ยังอยู่ในกล่องทราย: P ฉันกำลังคิดทบทวนจำนวนโบนัสเนื่องจากฉันตระหนักว่าแม้ใน Python (ภาษาค่อนข้างกระชับเมื่อเทียบกับ C # / Java) โบนัสไม่ได้ช่วย ฉันคิดว่าฉันจะทำให้มันสัมพันธ์กับความยาวของโปรแกรมเพื่อที่ภาษากอล์ฟจะไม่จบลงด้วยคะแนน <10 ไบต์
Kade

ฉันได้อัปเดตกฎโบนัสดังนั้นคะแนนใหม่ของคุณคือ 145.35 :)
Kade

บันทึกไบต์ลบเครื่องหมายอัฒภาคท้ายคำจำกัดความไม่จำเป็นดังนั้นหลังจากs++<999
Christopher Wirt

@ChristopherWirt ในคอมไพเลอร์ / รุ่นอะไร ฉันให้ข้อผิดพลาดทางไวยากรณ์โดยปราศจากมัน
Geobits

5

Ruby, (80 + 2) * 0.6 = ~ 49.2

ด้วยแฟล็-nlกรัน

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

ผลลัพธ์ดูเหมือนว่า

 $ 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

หากได้รับ 196 ก็พิมพ์ 261 nilขั้นตอนนอกจากนี้ยังเป็นครั้งแรกแล้ว

ไม่มีอะไรยุ่งยากเกินไปที่นี่ เราตรวจสอบว่า$_(ซึ่งถูกกำหนดค่าเริ่มต้นให้กับอินพุต) มีการย้อนกลับซึ่งเป็นไปได้ก็ต่อเมื่อมีขนาดเท่ากันเนื่องจากมีขนาดเท่ากัน หากเป็นเช่นนั้นเราพิมพ์จำนวนขั้นตอนและออกมิฉะนั้นเราจะแสดงและดำเนินการขั้นตอนนอกจากนี้การจัดเก็บค่าใหม่ใน$_(ผมโชคไม่ดีที่ไม่สามารถเพียงแค่evalสตริงฉันแสดงเพราะมันตีความจำนวนตรงกันข้ามกับท้าย 0 เป็นตัวอักษรฐานแปด) putsส่งคืนค่า falsey เพื่อให้ลูปดำเนินการต่อ


" + #{b} = "บันทึกเป็นไบต์
Mitch Schwartz

และดูเหมือนว่าภายในกฎที่จะวาง-lถ้าเราใส่ตัวเลขลงในไฟล์โดยไม่ต้องขึ้นบรรทัดใหม่และต่อท้ายไปป์?
Mitch Schwartz

4

Pyth - 19 ไบต์

ใช้ในขณะที่วงและเคาน์เตอร์ อาจมีอัลกอริทึมที่เล็กกว่านี้ แต่นี่ค่อนข้างสั้น

Wnz_z=z`+szs_z=hZ;Z

ลองมันออนไลน์ได้ที่นี่


เล็กมากจริง ๆ ! ทำได้ดีมาก :)
Kade

4

K, 25 ไบต์

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

ไม่ค่อยสง่างาม รูปแบบโดยรวม ( {monad 1}{monad 2}\x) เทียบเท่า K ของนายพล "ขณะที่" วงที่ monad xแรกคือสภาพลังเลและสองคือฟังก์ชั่นที่ใช้ซ้ำเพื่อโต้แย้ง Monad แรก ( {~x~|x}) คือการปฏิเสธของวลี "is xa palindrome" แบบคลาสสิก ที่สอง monad concatenates กันสตริงที่แสดง x บวกกลับของ x $ประเมินแล้วปลดเปลื้องกลับผลเป็นสตริงกับ

ตัวอย่างการรันแสดงผลลัพธ์ระดับกลาง:

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

การจัดรูปแบบผลลัพธ์ตามที่ร้องขอสำหรับโบนัสนั้นจะเงอะงะมากและเพิ่มรหัสจำนวนมาก


4

CJam, 23 ไบต์

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

เพียงไม่กี่วันใน CJam ดังนั้นฉันจึงค่อนข้างมีความสุขที่จะอยู่ในช่วงเดียวกับข้อดีบางประการ :) ฉันใช้เคล็ดลับการเปรียบเทียบสตริงของ Martin ที่เขาโพสต์ในคำใบ้ CJam ด้วย ฉันยังมองหาวิธีแก้ปัญหาของ Dennis เพื่อหาวิธีย้อนกลับสตริง

คำอธิบาย:

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.

ทดสอบออนไลน์


4

Julia, 129 120 bytes * 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)

สิ่งนี้จะสร้างฟังก์ชั่นที่ไม่มีชื่อซึ่งใช้จำนวนเต็มเป็นอินพุตและส่งกลับจำนวนเต็มขณะเดียวกันก็พิมพ์แต่ละขั้นตอน ผู้สมัคร Lychrel มีมูลค่าการกลับมาของ 262 f=i->...ในการโทรนี้ให้มันชื่อเช่น

โปรดทราบว่าการละเว้นรหัสที่เกี่ยวข้องกับโบนัสเท่านั้นวิธีนี้จะเป็น 84 ไบต์

คำอธิบาย Ungolfed +:

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

ตัวอย่าง:

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

บันทึก 2 ไบต์ต้องขอบคุณ Geobits!


4

CJam, 24 ไบต์

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

ทดสอบที่นี่

คำอธิบาย

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.

สำหรับข้อมูลเพิ่มเติมเกี่ยวกับสาเหตุที่#สามารถใช้เพื่อตรวจสอบความไม่เท่าเทียมกันของสตริงได้ที่เคล็ดลับนี้


ไม่เห็นคำตอบของคุณก่อนโพสต์ #นั่นคือใช้ฉลาดของ
Dennis

2

Haskell, 66 53 ไบต์

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

ตัวอย่างการใช้งาน:

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

ฉันไม่เคยใช้ Haskell มาก่อน แต่คุณสามารถทำr=reverse xอะไรได้บ้าง นั่นจะเปลี่ยนบรรทัดที่สองของคุณเป็นf x|x==r=0|1<2=1+f(show$read x+read(r))และบันทึก 2 ไบต์
Kade

@ Vioz-: ไม่นั่นเป็นไปไม่ได้เพราะxจะไม่อยู่ในขอบเขต อย่างไรก็ตามf x|x==r=0 .... read(r)) where r=reverse xจะใช้งานได้ แต่ใช้เวลานานกว่า
nimi

2

Clojure, 94 ไบต์

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

นี่เป็นครั้งแรกที่ฉันพยายามตีกอล์ฟดังนั้นโปรดบอกฉันว่าฉันทำอะไรผิดหรือเปล่า

ด้วยบางช่องว่าง:

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

การเรียกซ้ำแบบง่ายของฟังก์ชันภายใน มันต้องใช้สองข้อโต้แย้งจำนวนเต็ม%1และดัชนี%2และดัชนีถ้า%1เป็น palindrome ดัชนีจะถูกส่งคืน มิฉะนั้นฟังก์ชั่นเรียกตัวเองด้วยผลรวมและดัชนีที่เพิ่มขึ้น ฟังก์ชั่นด้านนอกเริ่มต้นดัชนีที่มีศูนย์

ตัวอย่าง:

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 ไบต์

ไม่ใช่ภาษาจริงๆ ยังคงเย็น

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

ค่อนข้างตรงไปตรงมานอกเหนือจากการแฮ็กข้อมูลตาม regex ที่ซับซ้อนฉันใช้เพื่อย้อนกลับสตริง


1

ทับทิม, 44

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

ต้องการ Ruby 1.9 หรือสูงกว่าสำหรับ->ไวยากรณ์แลมบ์ดา

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.