Hai palindromes là không đủ


24

Một số số, chẳng hạn như , là palindromes trong cơ sở 10: nếu bạn viết các chữ số theo thứ tự ngược lại, bạn sẽ nhận được cùng một số.14241

Một số số là tổng của 2 palindromes; ví dụ: hoặc .110= =88+222380= =939+1441

Đối với các số khác, 2 palindromes là không đủ; ví dụ, 21 không thể được viết dưới dạng tổng của 2 palindromes và điều tốt nhất bạn có thể làm là 3: .21= =11+9+1

Viết hàm hoặc chương trình lấy đầu vào số nguyên nvà xuất nsố thứ không thể phân tách thành tổng của 2 palindromes. Điều này tương ứng với OEIS A035137 .

Các chữ số đơn (bao gồm 0) là các palindromes.

Quy tắc chuẩn cho trình tự được áp dụng:

  • đầu vào / đầu ra linh hoạt
  • bạn có thể sử dụng lập chỉ mục 0- hoặc 1-
  • bạn có thể xuất ra nthuật ngữ thứ nhất, hoặc các nđiều khoản đầu tiên hoặc một chuỗi vô hạn

(Là một sidenote: tất cả các số nguyên có thể được phân tách thành tổng của tối đa 3 palindrome.)

Các trường hợp thử nghiệm (1 chỉ mục):

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

Đây là môn đánh gôn, vì vậy câu trả lời ngắn nhất sẽ thắng.


2
Không phải đầu ra vô hạn cũng là một tùy chọn tiêu chuẩn cho chuỗi?
Chuỗi không liên quan

@UnrelatedString Có, tôi cũng sẽ cho phép điều đó.
Robin Ryder


2
@ Abigail Cho số nguyên dương n, in thành viên thứ n của chuỗi OEIS An? Âm thanh đầy hứa hẹn ...
val nói Phục hồi

2
@Nit hãy định nghĩa một chuỗi OEIS mới là một (n) = chuỗi OEIS thứ n có thể được biểu thị bằng ít ký tự hơn hàm Jelly được đánh gôn nhất tạo ra chuỗi đó.
bất cứ

Câu trả lời:


13

JavaScript (ES6),  93 83 80  79 byte

Đã lưu 1 byte nhờ @tsh

Trả về số hạng thứ n , 1 chỉ mục.

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

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

Làm sao?

Cho n , chúng tôi kiểm tra xem có tồn tại bất kỳ 1kn sao cho cả kn-k đều là palindromes. Nếu chúng ta tìm thấy một k như vậy , thì n là tổng của hai palindromes.

Mẹo ở đây là xử lý kn-k cùng một lúc bằng cách kiểm tra một chuỗi đơn được tạo từ sự nối của k , n-kk .

Thí dụ:

Với n= =2380 :

  • cuối cùng chúng ta đạt k= =1441n-k= =939
  • chúng tôi kiểm tra chuỗi " 14419391441 " và phát hiện ra rằng đó là một bảng màu

Đã bình luận

NB: Đây là phiên bản không có eval()khả năng đọc.

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 byte
tsh

Thay vì i=>eval("..."), ES6 cho phép bạn sử dụng i=>eval`...`, tiết kiệm 2 byte
VFDan

Ngoài ra, nếu không có trả về được chỉ định, eval mặc định cho biểu thức cuối cùng được ước tính, do đó bạn có thể xóa ;nphần cuối.
VFDan

@VFDan Thủ thuật đánh dấu ngược không hoạt động eval()vì nó không ép buộc đối số của nó thành một chuỗi. Việc xóa ;nsẽ dẫn đến lỗi cú pháp và việc xóa chỉ nkhiến hàm trả về undefined.
Arnauld

12

Thạch ,  16 10  9 byte

-1 byte nhờ Erik the Outgolfer . Xuất ra các điều khoản n đầu tiên .

2_ŒḂƇ⁺ṆƲ#

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

Tôi đã cố gắng đưa ra ý tưởng khác biệt so với phương pháp ban đầu của tôi. Hãy xem lại quá trình suy nghĩ:

  • Ban đầu, thử nghiệm hoạt động như sau: Nó tạo ra các phân vùng nguyên của số đó, sau đó lọc ra những phân vùng không chứa palindromes, sau đó đếm xem có bao nhiêu danh sách đủ điều kiện có độ dài 2. Điều này rõ ràng là không quá hiệu quả về chiều dài mã.

  • Tạo các phân vùng số nguyên của N và sau đó lọc có 2 nhược điểm chính: hiệu quả thời lượng và thời gian. Để giải quyết vấn đề đó, trước tiên tôi nghĩ rằng tôi sẽ đưa ra một phương pháp để chỉ tạo ra các cặp số nguyên (x,y) có tổng bằng N (không phải tất cả các danh sách có độ dài tùy ý) với điều kiện cả hai số phải là bảng màu.

  • Tuy nhiên, tôi vẫn không hài lòng với "cách cổ điển" về việc này. Tôi đã chuyển đổi cách tiếp cận: thay vì tạo các cặp , hãy tập trung vào chương trình vào các palindromes cá nhân . Bằng cách này, người ta có thể chỉ cần tính toán tất cả các palindromes x bên dưới N và nếu Nx cũng là palindrom, thì chúng ta đã hoàn thành.

Giải thích mã

2_ŒḂƇ⁺ṆƲ # - Liên kết đơn âm hoặc Chương trình đầy đủ. Luận điểm: n.
2 # - Bắt đầu từ 2 * , tìm n số nguyên đầu tiên thỏa mãn ...
 _ŒḂƇ⁺ṆƲ - ... liên kết người trợ giúp. Phân tích (gọi số nguyên hiện tại N):
    Ƈ - Bộ lọc. Tạo phạm vi [1 ... N] và chỉ giữ những phạm vi ...
  ŒḂ - ... là các palindromes. Ví dụ: 21 -> [1,2,3,4,5,6,7,8,9,11]
 _ - Trừ từng palindrome từ N. Ví dụ: 21 -> [20,19, ..., 12,10]
     - Sao y liên kết trước đó (nghĩ về nó như thể có thêm
            thay vì ⁺). Điều này chỉ giữ các palindromes trong danh sách này.
            Nếu danh sách không trống, điều đó có nghĩa là chúng tôi đã tìm thấy một cặp (x, Nx)
            chứa hai palindromes (và rõ ràng x + Nx = N để chúng tổng hợp thành N).
      - Logic KHÔNG (chúng tôi đang tìm kiếm các số nguyên mà danh sách này trống).
       - Nhóm 4 liên kết cuối cùng (về cơ bản làm cho _ŒḂƇ⁺Ṇ hoạt động như một đơn nguyên).

* Bất kỳ chữ số khác không hoạt động, cho vấn đề đó.


7

Thạch , 11 byte

⁵ŻŒḂ€aṚ$EƲ#

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

Chương trình đầy đủ đại khái hoạt động như thế này:

  1. Đặt z thành đầu vào.
  2. Đặt x thành 10 .
  3. Đặt R thành [] .
  4. Với mọi số nguyên k từ 0 đến và bao gồm x , hãy kiểm tra xem cả kx - k có phải là palindromic không.
  5. Nếu tất cả các phần tử của L đều bằng nhau (nghĩa là, nếu tất cả các cặp có thể có tổng bằng x đều có cả hai phần tử của chúng, hoặc tất cả các cặp như vậy có nhiều nhất một phần tử của chúng là palindromic), đặt z thành z - 1 và nối x để R .
  6. Nếu z = 0 , trả về R và kết thúc.
  7. Đặt x thành x + 1 .
  8. Chuyển đến bước 4.

Bạn có thể nghi ngờ rằng bước 5 không thực sự làm công việc cần làm. Chúng ta thực sự không nên giảm z nếu tất cả các cặp có tổng bằng x là palindromic. Tuy nhiên, chúng tôi có thể chứng minh rằng điều này sẽ không bao giờ xảy ra:

Trước tiên hãy chọn một số nguyên k sao cho 10kx . Chúng ta luôn có thể làm như vậy, bởi vì, ở bước 2, chúng ta khởi tạo x thành 10 .

Nếu k không phải là một palindrom, thì chúng ta có cặp (k,x-k) , trong đó k+(x-k)= =x , do đó không phải tất cả các cặp đều có hai palindromes.

Mặt khác, nếu k là một palindrom, thì chúng ta có thể chứng minh rằng k-1 không phải là một palindrom. Đặt các chữ số đầu tiên và cuối cùng của k lần lượt là DFDLk là một palindrom, DF= =DL>0 . Hãy để cho chữ số đầu tiên và cuối cùng của k-1 be DF'DL' tương ứng. Kể từ DL>0 , DL'= =DF'-1DF' . Do đó,k-1 không phải là một palindrom và chúng ta có cặp(k-1,x-(k-1)) , trong đó(k-1)+(x-(k-1))= =k-1+x-k+1= =x .

Chúng tôi kết luận rằng, nếu chúng tôi bắt đầu với việc đặt x thành giá trị lớn hơn hoặc bằng 10 , chúng tôi không bao giờ có thể có tất cả các cặp số nguyên không âm có tổng bằng x là cặp palindromes.


À, đánh tôi cũng được - điều khoản n đầu tiên tiết kiệm 1 byte (tôi đã đi STDIN vàŻŒḂ€aṚ$Ṁ¬µ#
Jonathan Allan

@Jonathan ALLan Oh LOL không mong đợi điều đó. Dù sao, ai đó đã đánh bại cả hai chúng tôi. : D
Erik the Outgolfer

(10,x-10)10

11

3

Võng mạc , 135 102 byte

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

Hãy thử trực tuyến! Quá chậm cho ntừ 10 trở lên. Giải trình:

K`0

Bắt đầu bằng cách thử 0.

"$+"{

Lặp lại nnhiều lần.

0L$`\d+
*__

Chuyển đổi giá trị dùng thử hiện tại thành đơn nguyên và tăng nó.

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

Tạo tất cả các cặp số nguyên không âm tổng hợp với giá trị dùng thử mới.

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

Lặp lại trong khi tồn tại ít nhất một cặp chứa hai số nguyên palindromic.

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

Tăng và mở rộng giá trị dùng thử một lần nữa.

0L`\d+

Trích xuất giá trị cuối cùng.


3

Haskell, 68 67 63 byte

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

Trả về một chuỗi vô hạn.

Thu thập tất cả những nnơi ahoặc n-akhông phải là một bảng màu cho tất cả a <- [0..n].

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


3

Perl 5 -MList::Util=any -p , 59 55 byte

-3 byte nhờ @NahuelFouilleul

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

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

Lưu ý: anycó thể được thay thế bằng grepvà tránh -Mchuyển đổi dòng lệnh, nhưng theo quy tắc tính điểm hiện tại, điều đó sẽ tốn thêm một byte.


cải thiện nhỏ, -3byte , sử dụng trong khi thay vì làm lại
Nahuel Fouilleul

Và lấy thêm một trong số đó bằng cách loại bỏ +sau while.
Xcali

3

R , 115 111 byte

-4 cảm ơn Giuseppe

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]

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

Hầu hết các công việc được đóng gói vào các đối số hàm để loại bỏ {}lệnh gọi hàm đa câu lệnh và để giảm dấu ngoặc cần thiết trong việc xác định đối tượngr

Chiến lược cơ bản là tìm tất cả các palindromes đến một giới hạn nhất định (bao gồm 0), tìm tất cả các tổng cặp, và sau đó lấy số thứ n không có trong đầu ra đó.

Giới hạn của n*1000được chọn hoàn toàn từ một phỏng đoán có giáo dục, vì vậy tôi khuyến khích bất cứ ai chứng minh / từ chối nó như là một lựa chọn hợp lệ.

r=0:(n*1e3)có lẽ có thể được cải thiện với một ràng buộc hiệu quả hơn.

Map(paste,Map(rev,strsplit(a,"")),collapse="")được trích từ câu trả lời của Mark ở đây , và tôi cực kỳ thông minh.

r[!r%in%outer(p,p,'+')][n]đọc một chút không hiệu quả với tôi.


1
111 byte chỉ bằng cách sắp xếp lại một vài thứ.
Giuseppe


1

J , 57/60 byte

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

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

Phiên bản được liên kết thêm 3 byte cho tổng số 60 để lưu dưới dạng hàm mà chân trang có thể gọi.

Trong REPL, điều này được tránh bằng cách gọi trực tiếp:

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

Giải trình

Cấu trúc chung là kỹ thuật này từ câu trả lời của 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

Điều này đã lưu một vài byte so với kỹ thuật lặp ban đầu của tôi, nhưng vì chức năng cốt lõi là nỗ lực đầu tiên của tôi khi viết J, nên có nhiều khả năng vẫn có thể được cải thiện.

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.

Đó là một định dạng cũ của tôi, kết hợp thủ thuật khác mà tôi học được từ đó tạo ra một giải pháp 41 char:1&(_:1&((e.((*&(-:|.)&":"0>:)&i.-))+])+)*
dặm

1

05AB1E , 15 12 byte

°ÝDʒÂQ}ãOKIè

-3 byte nhờ @Grimy .

Chỉ số 0.
Rất chậm, vì vậy thời gian ra cho hầu hết các trường hợp thử nghiệm.

Hãy thử trực tuyến hoặc xác minh một vài trường hợp đầu tiên bằng cách xóa .

Phiên bản 15 byter nhanh hơn nhiều:

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

1 chỉ mục.

n

Giải trình:

°Ý              # 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è(có lẽ có giới hạn trên tốt hơn 10 ^ x cho tốc độ). Tôi đoán ∞DʒÂQ}ãOKvề mặt kỹ thuật là 9, nhưng nó hết thời gian trước khi đầu ra đầu tiên.
Grimmy

@Grimy Không chắc chắn nếu sản phẩm cartesian hoạt động lười biếng trong danh sách vô hạn. Dù sao, đối với 12 -ter, thật không may là không chính xác. Nó lọc ra các số nguyên có thể được hình thành bằng cách tính tổng 2 palindromes, nhưng không lọc các số nguyên là chính các palindromes. Trình tự của bạn (không có dấu vết ) đi như sau: [1,21,32,43,54,65,76,87,98,111,131,141,151,...]nhưng được cho là đi [*,21,32,43,54,65,76,87,98,201,1031,1041,1051,1052,...](đầu tiên 1/ *có thể bị bỏ qua vì chúng tôi sử dụng đầu vào 1 chỉ mục).
Kevin Cruijssen

1
@Grimy Hmm, tôi đoán một bản sửa lỗi thẳng đang thay đổi danh sách dựa trên 1 Lthành 0 dựa trên .. :)
Kevin Cruijssen


0

Python 3 , 107 byte

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

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

Đảo ngược việc kiểm tra palindrom đã lưu 2 byte :)

Để tham khảo, kiểm tra dương tính thẳng (109 byte):

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 byte

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

Từ để phá vỡ vòng lặp là gì? Có vẻ như đó là ": rời đi", phải không? {k≡⌽k←⍕⍵}trong p là bài kiểm tra cho palindrom. Hàm trên này trong vòng lặp lưu trữ tất cả các palindrom được tìm thấy trong tập P, nếu đối với một số phần tử w của P thì iw nằm trong P cũng có nghĩa là i không đúng và chúng ta có i tăng. Các kết quả:

  f 1
21
  f 2
32
  f 10
1031
  f 16
1061
  f 40
1103
  f 1000
4966
  f 1500
7536
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.