สอง palindromes ไม่เพียงพอ


24

ตัวเลขบางตัวเช่น14241เป็น palindromes ในฐาน 10: ถ้าคุณเขียนตัวเลขในลำดับที่กลับกันคุณจะได้รับหมายเลขเดียวกัน

ตัวเลขบางตัวเป็นผลรวมของ 2 palindromes; ตัวอย่างเช่น110=88+22หรือ2380=939+1441 1441

สำหรับตัวเลขอื่น ๆ 2 palindromes ไม่เพียงพอ; ตัวอย่างเช่น 21 ไม่สามารถเขียนเป็นผลรวมของ 2 palindromes และดีที่สุดที่คุณสามารถทำได้คือ 3: 21=11+9+1 1

เขียนฟังก์ชั่นหรือโปรแกรมที่รับอินพุตจำนวนเต็มnและส่งออกnตัวเลข th ซึ่งไม่สามารถย่อยสลายเป็นผลรวมของ 2 palindromes สอดคล้องกับการนี้OEIS A035137

ตัวเลขหลักเดียว (รวมถึง 0) คือ palindromes

ใช้กฎมาตรฐานสำหรับลำดับดังนี้:

  • อินพุต / เอาต์พุตมีความยืดหยุ่น
  • คุณอาจใช้การจัดทำดัชนี 0- หรือ 1-
  • คุณอาจส่งออกnคำที่หรือระยะแรกnหรือลำดับที่ไม่มีที่สิ้นสุด

(ในฐานะ sidenote: จำนวนเต็มทั้งหมดสามารถแยกย่อยเป็นผลรวมของ palindromes ได้สูงสุด 3 รายการ)

กรณีทดสอบ (1 ดัชนี):

1 -> 21
2 -> 32
10 -> 1031
16 -> 1061
40 -> 1103

นี่คือรหัสกอล์ฟดังนั้นคำตอบที่สั้นที่สุดชนะ


2
เอาต์พุตไม่สิ้นสุดเป็นตัวเลือกมาตรฐานสำหรับลำดับหรือไม่
สตริงที่ไม่เกี่ยวข้อง

@ UnrelatedString ใช่ฉันจะอนุญาตด้วย
Robin Ryder


2
@Abigail รับจำนวนเต็มบวกnพิมพ์ลำดับที่ n สมาชิกลำดับที่ OEIS? ฟังดูมีแนวโน้ม ...
วาลพูดว่า Reinstate Monica

2
@Nit ลองกำหนดลำดับ OEIS ใหม่เป็น (n) = ลำดับที่ OEIS ที่สามารถแสดงเป็นตัวอักษรน้อยกว่าฟังก์ชั่นเยลลี่ golfed ส่วนใหญ่ที่สร้างลำดับนั้น
ทุกที่

คำตอบ:


13

JavaScript (ES6),  93 83 80  79 ไบต์

บันทึกแล้ว 1 ไบต์ขอบคุณ @tsh

ส่งกลับn THระยะ 1 การจัดทำดัชนี

i=>eval("for(n=k=1;k=(a=[...k+[n-k]+k])+''!=a.reverse()?k-1||--i&&++n:++n;);n")

ลองออนไลน์!

อย่างไร?

รับnเราทดสอบว่ามี1knไม่ว่าทั้งkและnkเป็น palindromes หากเราพบkอย่างนั้นnก็คือผลรวมของสอง palindromes

เคล็ดลับที่นี่คือการกระบวนการkและnkในเวลาเดียวกันโดยการทดสอบสายเดียวที่ทำจากการเรียงต่อกันของk , nkและkk

ตัวอย่าง:

สำหรับn=2380 :

  • ในที่สุดเราถึงk=1441และnk=939
  • เราทดสอบสตริง " 14419391441 " และค้นหาว่าเป็น Palindrome

แสดงความคิดเห็น

หมายเหตุ: นี่เป็นรุ่นที่ไม่มีeval()การอ่านได้

i => {                       // i = index of requested term (1-based)
  for(                       // for loop:
    n = k = 1;               //   start with n = k = 1
    k =                      //   update k:
      ( a =                  //     split and save in a[] ...
        [...k + [n - k] + k] //     ... the concatenation of k, n-k and k
      ) + ''                 //     coerce it back to a string
      != a.reverse() ?       //     if it's different from a[] reversed:
        k - 1                //       decrement k; if the result is zero:
          || --i             //         decrement i; if the result is not zero:
            && ++n           //           increment n (and update k to n)
                             //         (otherwise, exit the for loop)
      :                      //     else:
        ++n;                 //       increment n (and update k to n)
  );                         // end of for
  return n                   // n is the requested term; return it
}                            //

i=>eval("for(n=k=1;k=(s=[...k+[n-k]+k])+''!=s.reverse()?k-1||i--&&++n:++n;);n")79 bytes
tsh

แทนi=>eval("...")ES6 ให้คุณใช้i=>eval`...`ประหยัด 2 ไบต์
VFDan

นอกจากนี้หากไม่ได้ระบุผลตอบแทนไว้ Eval จะใช้ค่าเริ่มต้นเป็นนิพจน์สุดท้ายที่ประเมินค่าเพื่อให้คุณสามารถลบ;nส่วนท้ายได้
VFDan

@VFDan เคล็ดลับการย้อนกลับไม่ทำงานeval()เนื่องจากไม่ได้บังคับใช้อาร์กิวเมนต์กับสตริง การถอด;nจะนำไปสู่ข้อผิดพลาดทางไวยากรณ์และลบเพียงจะทำให้เกิดการทำงานเพื่อผลตอบแทนn undefined
Arnauld

12

เยลลี่ ,  16 10  9 ไบต์

-1 ขอบคุณไบต์เอริก Outgolfer ขาออกแรกnแง่

2_ŒḂƇ⁺ṆƲ#

ลองออนไลน์!

ฉันพยายามคิดหาวิธีที่แตกต่างจากวิธีดั้งเดิมของฉัน ลองทบทวนกระบวนการคิด:

  • ในขั้นต้นการทดสอบทำงานดังนี้: มันสร้างพาร์ติชั่นเลขจำนวนเต็มของหมายเลขนั้นจากนั้นกรองพาร์ติชั่นที่มีปาลิโนไมมิที่ไม่ใช่จากนั้นนับจำนวนรายการที่มีความยาว -2 ที่มีสิทธิ์ เห็นได้ชัดว่านี่ไม่ได้มีประสิทธิภาพมากเกินไปในแง่ของความยาวโค้ด

  • การสร้างพาร์ทิชันจำนวนเต็มของNจากนั้นการกรองมีข้อเสีย 2 ประการคือความยาวและประสิทธิภาพของเวลา ในการแก้ปัญหานั้นฉันคิดว่าฉันจะหาวิธีสร้างจำนวนคู่เท่านั้น(x,y)ที่รวมกับN (ไม่ใช่รายการความยาวโดยพลการทั้งหมด) โดยมีเงื่อนไขว่าตัวเลขทั้งสองจะต้องเป็นโทนสี

  • แต่ถึงกระนั้นฉันไม่พอใจกับ "วิธีคลาสสิก" ของการทำเช่นนี้ ฉันเปลี่ยนวิธีการ: แทนที่จะสร้างคู่เราจะให้โปรแกรมเน้นที่palindromesแต่ละตัว ด้วยวิธีนี้เราสามารถคำนวณ palindromes xด้านล่างNทั้งหมดได้และถ้าNxเป็น Palindrome ด้วยเราก็เสร็จแล้ว

รหัสคำอธิบาย

2_ŒḂƇ⁺ṆƲ # - ลิงก์ Monadic หรือโปรแกรมเต็ม อาร์กิวเมนต์: n
2 # - เริ่มต้นที่ 2 *ค้นหาจำนวนเต็ม n ตัวแรกที่ตรงกับ ...
 _ŒḂƇ⁺ṆƲ - ... ลิงก์ผู้ช่วย รายละเอียด (เรียกเลขจำนวนเต็มปัจจุบัน N):
    Ƈ - ตัวกรอง สร้างช่วง [1 ... N] และเก็บเฉพาะที่ ...
  ŒḂ - ... เป็น palindromes ตัวอย่าง: 21 -> [1,2,3,4,5,6,7,8,9,11]
 _ - ลบ Palindromes แต่ละอันออกจาก N ตัวอย่าง: 21 -> [20,19, ... , 12,10]
     ⁺ - ทำซ้ำลิงก์ก่อนหน้า (ลองคิดดูว่ามี additional เพิ่มอีก
            แทน⁺) นี่จะเก็บ palindromes ในรายการนี้เท่านั้น
            หากรายการนั้นไม่ว่างนั่นหมายความว่าเราพบคู่ (x, Nx) แล้ว
            มีสอง palindromes (และชัด x + Nx = N ดังนั้นพวกเขารวมถึง N)
      Ṇ - ตรรกะไม่ได้ (เรากำลังมองหาจำนวนเต็มที่รายการนี้ว่างเปล่า)
       Ʋ - จัดกลุ่มลิงก์ 4 รายการสุดท้าย (โดยทั่วไปทำให้_ŒḂƇ⁺Ṇทำหน้าที่เป็น monad เดียว)

* งานอื่น ๆ ที่ไม่ใช่ศูนย์หลักสำหรับเรื่องนั้น


7

เยลลี่ 11 ไบต์

⁵ŻŒḂ€aṚ$EƲ#

ลองออนไลน์!

โปรแกรมเต็มรูปแบบทำงานได้อย่างคร่าวๆดังนี้:

  1. ตั้งค่าzเป็นอินพุต
  2. ชุดxไป10
  3. ชุดRเพื่อ[]
  4. สำหรับทุกจำนวนเต็มkจาก0ถึงและรวมxตรวจสอบว่าทั้งkและx - kเป็น palindromic
  5. หากองค์ประกอบทั้งหมดของLมีค่าเท่ากัน (นั่นคือถ้าคู่ที่เป็นไปได้ทั้งหมดที่รวมกับxมีทั้งองค์ประกอบของ palindromic หรือคู่ดังกล่าวทั้งหมดมีองค์ประกอบของพวกเขาเป็น palindromic มากที่สุด) ตั้งค่าzเป็นz - 1และผนวกxเพื่อR
  6. ถ้าz = 0ให้ส่งคืนRและสิ้นสุด
  7. ชุดxเพื่อx + 1
  8. ไปที่ขั้นตอนที่ 4

คุณอาจสงสัยว่าขั้นตอนที่ 5 ไม่ได้ทำงานจริงตามที่ควร เราไม่ควรลดทอนzถ้าคู่ทั้งหมดที่รวมกับxเป็น palindromic อย่างไรก็ตามเราสามารถพิสูจน์ได้ว่าสิ่งนี้จะไม่เกิดขึ้น:

k10kx

k(k,xk)k+(xk)=x

kk1kDFDLkDF=DL>0k1DFDLDL>0DL=DF1DFk1(k1,x(k1))(k1)+(x(k1))=k1+xk+1=x

เราสรุปได้ว่าถ้าเราเริ่มต้นด้วยการตั้งค่าxเป็นค่าที่มากกว่าหรือเท่ากับ10เราจะไม่มีคู่ที่ไม่เป็นลบทั้งหมดที่รวมเป็นxเป็นคู่ของ palindromes


อ่าเอาชนะฉันด้วย - ข้อตกลง n ข้อแรกช่วยประหยัด 1 ไบต์ (ฉันไปหา STDIN และŻŒḂ€aṚ$Ṁ¬µ#
Jonathan Allan

@JanathanAllan Oh LOL ไม่ได้คาดหวังสิ่งนั้น อย่างไรก็ตามมีคนชนะเราทั้งคู่ : D
Erik the Outgolfer

(10,x10)10

11

3

เรติน่า , 135 102 ไบต์

K`0
"$+"{0L$`\d+
*__
L$`
<$.'>$.`>
/<((.)*.?(?<-2>\2)*(?(2)$)>){2}/{0L$`\d+
*__
))L$`
<$.'>$.`>
0L`\d+

ลองออนไลน์! ช้าไปnกว่า 10 ครั้งขึ้นไป คำอธิบาย:

K`0

เริ่มต้นด้วยการลอง 0

"$+"{

ทำซ้ำnครั้ง

0L$`\d+
*__

แปลงค่าการทดลองปัจจุบันเป็น unary และเพิ่มขึ้น

L$`
<$.'>$.`>

สร้างคู่จำนวนเต็มที่ไม่เป็นลบทั้งหมดที่รวมกับค่าทดลองใหม่

/<((.)*.?(?<-2>\2)*(?(2)$)>){2}/{

ทำซ้ำในขณะที่มีอยู่อย่างน้อยหนึ่งคู่ที่มีจำนวนเต็ม palindromic สองตัว

0L$`\d+
*__
))L$`
<$.'>$.`>

เพิ่มและขยายค่ารุ่นทดลองอีกครั้ง

0L`\d+

แยกค่าสุดท้าย


3

Haskell, 68 67 63 ไบต์

[n|n<-[1..],and[p a||p(n-a)|a<-[0..n]]]
p=((/=)=<<reverse).show

ส่งคืนลำดับที่ไม่มีที่สิ้นสุด

การเก็บรวบรวมทั้งหมดnที่ทั้งสองaหรือn-aไม่ palindrome a <- [0..n]สำหรับทุก

ลองออนไลน์!


3

Perl 5 -MList::Util=any -p , 59 55 ไบต์

-3 ไบต์ขอบคุณ @NahuelFouilleul

++$\while(any{$\-reverse($\-$_)==reverse}0..$\)||--$_}{

ลองออนไลน์!

หมายเหตุ: anyอาจถูกแทนที่ด้วยgrepและหลีกเลี่ยงการ-Mสลับบรรทัดคำสั่ง แต่ภายใต้กฎการให้คะแนนปัจจุบันจะมีค่าใช้จ่ายมากกว่าหนึ่งไบต์


การปรับปรุงเล็ก ๆ น้อย ๆ-3bytesใช้แทนการทำซ้ำ
Nahuel Fouilleul

และเอาอีกหนึ่งออกจากที่โดยการกำจัดหลัง+ while
Xcali

3

R , 115 111 ไบต์

-4 ขอบคุณจูเซปเป้

function(n,r=0:(n*1e3))r[!r%in%outer(p<-r[Map(Reduce,c(x<-paste0),Map(rev,strsplit(a<-x(r),"")))==a],p,'+')][n]

ลองออนไลน์!

งานส่วนใหญ่บรรจุอยู่ในอาร์กิวเมนต์ของฟังก์ชั่นเพื่อลบการ{}เรียกใช้ฟังก์ชั่นหลายคำสั่งและเพื่อลดวงเล็บที่จำเป็นในการกำหนดวัตถุr

กลยุทธ์พื้นฐานคือการหา palindromes ทั้งหมดจนถึงขอบเขตที่กำหนด (รวมถึง 0), หาผลรวมของจำนวนคู่ทั้งหมดแล้วนำตัวเลข n-th ไปไม่ได้ในผลลัพธ์นั้น

ขอบเขตของn*1000ได้รับเลือกอย่างหมดจดจากการเดาที่มีการศึกษาดังนั้นฉันขอแนะนำให้ทุกคนที่พิสูจน์ / หักล้างมันเป็นตัวเลือกที่ถูกต้อง

r=0:(n*1e3)สามารถปรับปรุงได้ด้วยขอบเขตที่มีประสิทธิภาพมากขึ้น

Map(paste,Map(rev,strsplit(a,"")),collapse="")ถูกริปจากคำตอบของมาร์คที่นี่และฉลาดสำหรับฉันอย่างไม่น่าเชื่อ

r[!r%in%outer(p,p,'+')][n]อ่านน้อยไม่มีประสิทธิภาพให้ฉัน


1
111 ไบต์เพียงแค่จัดเรียงสิ่งใหม่ ๆ
Giuseppe


1

J , 57/60 ไบต์

0(](>:^:(1&e.p e.]-p=:(#~(-:|.)&":&>)&i.&>:)^:_)&>:)^:[~]

ลองออนไลน์!

เวอร์ชันที่ลิงก์เพิ่ม 3 ไบต์รวมเป็น 60 เพื่อบันทึกเป็นฟังก์ชันที่ส่วนท้ายสามารถโทรได้

ใน REPL จะหลีกเลี่ยงได้โดยการโทรโดยตรง:

   0(](>:^:(1 e.q e.]-q=:(#~(-:|.)&":&>)&i.&>:)^:_)&>:)^:[~] 1 2 10 16 40
21 32 1031 1061 1103

คำอธิบาย

โครงสร้างทั่วไปคือเทคนิคนี้จากคำตอบของMiles :

(s(]f)^:[~]) n
          ]  Gets n
 s           The first value in the sequence
         ~   Commute the argument order, n is LHS and s is RHS
        [    Gets n
      ^:     Nest n times with an initial argument s
  (]f)         Compute f s
         Returns (f^n) s

สิ่งนี้บันทึกไว้เพียงไม่กี่ไบต์กับเทคนิคการวนลูปดั้งเดิมของฉัน แต่เนื่องจากฟังก์ชั่นหลักคือความพยายามครั้งแรกของฉันในการเขียน J จึงมีโอกาสมากที่จะสามารถปรับปรุงได้

0(](>:^:(1&e.p e.]-p=:(#~(-:|.)&":&>)&i.&>:)^:_)&>:)^:[~]
0(]                                                 ^:[~] NB. Zero as the first term switches to one-indexing and saves a byte.
   (>:^:(1&e.p e.]-p=:(#~(-:|.)&":&>)&i.&>:)^:_)&>:)      NB. Monolithic step function.
                                                 >:       NB. Increment to skip current value.
   (>:^: <predicate>                        ^:_)          NB. Increment current value as long as predicate holds.
                   p=:(#~(-:|.)&":&>)&i.&>:               NB. Reused: get palindromes in range [0,current value].
                       #~(-:|.)&":&>                      NB. Coerce to strings keeping those that match their reverse.
                 ]-p                                      NB. Subtract all palindromes in range [0,current value] from current value.
    >:^:(1&e.p e.]-p                                      NB. Increment if at least one of these differences is itself a palindrome.

นั่นเป็นรูปแบบเก่าของฉันที่รวมเทคนิคอื่น ๆ ที่ฉันได้เรียนรู้นับ แต่นั้นก็สร้างโซลูชันถ่าน 41 ตัว:1&(_:1&((e.((*&(-:|.)&":"0>:)&i.-))+])+)*
ไมล์

1

05AB1E , 15 12 ไบต์

°ÝDʒÂQ}ãOKIè

-3 ไบต์ขอบคุณที่@Grimy

0 การจัดทำดัชนี
ช้ามากจึงหมดเวลาสำหรับกรณีทดสอบส่วนใหญ่

ลองมันออนไลน์หรือตรวจสอบบางกรณีแรกโดยการเอา

เร็วกว่า 15 byter รุ่นก่อนหน้า:

µNÐLʒÂQ}-ʒÂQ}g_

1 การจัดทำดัชนี

n

คำอธิบาย:

°Ý              # Create a list in the range [0, 10**input]
  D             # Duplicate this list
   ʒÂQ}         # Filter it to only keep palindromes
       ã        # Take the cartesian product with itself to create all possible pairs
        O       # Sum each pair
         K      # Remove all of these sums from the list we duplicated
          Iè    # Index the input-integer into it
                # (after which the result is output implicitly)

µ               # Loop until the counter variable is equal to the (implicit) input-integer
 NÐ             #  Push the loop-index three times
   L            #  Create a list in the range [1, N] with the last copy
    ʒÂQ}        #  Filter it to only keep palindromes
        -       #  Subtract each from N
         ʒÂQ}   #  Filter it again by palindromes
             g_ #  Check if the list is empty
                #   (and if it's truthy: increase the counter variable by 1 implicitly)
                # (after the loop: output the loop-index we triplicated implicitly as result)

1
12: °LDʒÂQ}ãOKIè(อาจมีขอบเขตบนที่ดีกว่า 10 ^ x สำหรับความเร็ว) ฉันเดาว่า∞DʒÂQ}ãOKเป็นเทคนิค 9 แต่หมดเวลาก่อนที่จะออกแรก
Grimmy

@Grimy ไม่แน่ใจว่าผลิตภัณฑ์คาร์ทีเซียนนั้นทำงานได้อย่างอิสระในรายการไม่สิ้นสุดหรือไม่ อย่างไรก็ตามสำหรับ 12-byter น่าเสียดายที่มันไม่ถูกต้อง มันกรองจำนวนเต็มที่สามารถเกิดขึ้นได้จากการรวม 2 palindromes แต่ไม่ใช่จำนวนเต็มที่ palindromes ลำดับของคุณ (ไม่มีส่วนท้าย) จะเป็นเช่น: [1,21,32,43,54,65,76,87,98,111,131,141,151,...]แต่ควรจะเป็นเช่นนั้น[*,21,32,43,54,65,76,87,98,201,1031,1041,1051,1052,...](ลำดับแรก1/ *สามารถถูกละเว้นได้เนื่องจากเราใช้อินพุตแบบดัชนี 1 รายการ)
Kevin Cruijssen

1
@Grimy อืมฉันคิดว่าการแก้ไขแบบตรงไปข้างหน้ากำลังเปลี่ยนรายการที่ใช้ 1 รายการLเป็นแบบอิง 0 .. :)
Kevin Cruijssen


0

Python 3 , 107 ไบต์

p=lambda n:str(n)!=str(n)[::-1]
def f(n):
 m=1
 while n:m+=1;n-=all(p(k)+p(m-k)for k in range(m))
 return m

ลองออนไลน์!

การทำการตรวจสอบ palindrome ที่บันทึกไว้ 2 ไบต์ :)

สำหรับการอ้างอิงการตรวจสอบเชิงบวกแบบตรงไปข้างหน้า (109 ไบต์):

p=lambda n:str(n)==str(n)[::-1]
def f(n):
 m=1
 while n:m+=1;n-=1-any(p(k)*p(m-k)for k in range(m))
 return m

0

APL (NARS) 486 ไบต์

r←f w;p;i;c;P;m;j
p←{k≡⌽k←⍕⍵}⋄i←c←0⋄P←r←⍬
:while c<w
    i+←1
    :if   p i⋄P←P,i⋄:continue⋄:endif
    m←≢P⋄j←1
    :while j≤m
         :if 1=p i-j⊃P⋄:leave⋄:endif
         j+←1
    :endwhile
    :if j=m+1⋄c+←1⋄r←i⋄:endif
:endwhile

คำว่าแบ่งลูปคืออะไร ดูเหมือนว่าจะเป็น ": ปล่อย" ใช่ไหม? {k≡⌽k←⍕⍵}ใน p คือการทดสอบสำหรับ Palindrome ฟังก์ชั่นด้านบนนี้ใน loop store palindrome ทั้งหมดที่พบในชุด P หากองค์ประกอบบางส่วนของ P เป็นเช่นนั้นที่ iw อยู่ใน P ด้วยนี่หมายความว่า i ไม่ถูกต้องและเราเพิ่ม i ผล:

  f 1
21
  f 2
32
  f 10
1031
  f 16
1061
  f 40
1103
  f 1000
4966
  f 1500
7536
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.