Dua palindrom tidak cukup

24

Beberapa angka, seperti 14241 , adalah palindrom di basis 10: jika Anda menulis angka dalam urutan terbalik, Anda mendapatkan nomor yang sama.

Beberapa angka adalah jumlah dari 2 palindrom; misalnya, 110=88+22 , atau 2380=939+1441 .

Untuk nomor lain, 2 palindrom tidak cukup; misalnya, 21 tidak dapat ditulis sebagai jumlah dari 2 palindrom, dan yang terbaik yang dapat Anda lakukan adalah 3: 21=11+9+1 .

Tulis fungsi atau program yang mengambil input bilangan bulat ndan mengeluarkan angka nke-2 yang tidak dapat didekomposisi sebagai jumlah dari 2 palindrom. Ini sesuai dengan OEIS A035137 .

Digit tunggal (termasuk 0) adalah palindrom.

Aturan standar untuk urutan berlaku:

  • input / output fleksibel
  • Anda dapat menggunakan 0- atau 1- pengindeksan
  • Anda dapat menampilkan nistilah th, atau nistilah pertama , atau urutan yang tak terbatas

(Sebagai sidenote: semua bilangan bulat dapat didekomposisi sebagai jumlah paling banyak 3 palindrom.)

Kasus uji (1-diindeks):

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

Ini kode-golf, jadi jawaban terpendek menang.

Robin Ryder
sumber
2
Bukankah output yang tak terbatas juga merupakan opsi standar untuk sekuens?
String Tidak Terkait
@UnrelatedString Ya, saya akan mengizinkannya juga.
Robin Ryder
Terkait
Luis Mendo
2
@Abigail Diberikan bilangan bulat positif n, cetak urutan ke-n dari urutan OEIS An? Kedengarannya menjanjikan ...
val berkata Reinstate Monica
2
@Nit mari kita mendefinisikan urutan OEIS baru sebagai (n) = urutan OEIS ke-n yang dapat diekspresikan dalam karakter kurang dari fungsi Jelly paling golf yang menghasilkan urutan itu.
agtoever

Jawaban:

13

JavaScript (ES6),  93 83 80  79 byte

Disimpan 1 byte berkat @tsh

Mengembalikan istilah ke- n , 1-diindeks.

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

Cobalah online!

Bagaimana?

Diberikan n , kami menguji apakah ada 1kn sedemikian rupa sehingga k dan nk adalah palindrom. Jika kita menemukan k seperti itu , maka n adalah jumlah dari dua palindrom.

Kuncinya di sini adalah untuk memproses k dan nk pada saat yang sama dengan menguji satu string yang terbuat dari gabungan k , nk dan k .

Contoh:

Untuk n=2380 :

  • kita akhirnya mencapai k=1441 dan nk=939
  • kami menguji string " 14419391441 " dan mengetahui bahwa itu adalah palindrom

Berkomentar

NB: Ini adalah versi tanpa eval()keterbacaan.

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
}                            //
Arnauld
sumber
i=>eval("for(n=k=1;k=(s=[...k+[n-k]+k])+''!=s.reverse()?k-1||i--&&++n:++n;);n")79 byte
tsh
Alih-alih i=>eval("..."), ES6 memungkinkan Anda untuk menggunakan i=>eval`...`, menghemat 2 byte
VFDan
Juga, jika tidak ada pengembalian yang ditentukan, eval default ke ekspresi terakhir yang dievaluasi, sehingga Anda dapat menghapus ;ndi akhir.
VFDan
@VFDan Trik centang-belakang tidak berfungsi eval()karena tidak memaksa argumennya menjadi string. Menghapus ;nakan menyebabkan kesalahan sintaks dan menghapus hanya nakan menyebabkan fungsi kembali undefined.
Arnauld
12

Jelly ,  16 10  9 byte

-1 byte terima kasih kepada Erik the Outgolfer . Menghasilkan n istilah pertama .

2_ŒḂƇ⁺ṆƲ#

Cobalah online!

Saya mencoba untuk datang dengan ide yang berbeda dibandingkan dengan pendekatan awal saya. Mari kita tinjau proses berpikir:

  • Awalnya, tes bekerja sebagai berikut: Ini menghasilkan partisi bilangan bulat dari angka itu, kemudian menyaring yang juga mengandung non-palindrom, kemudian menghitung berapa panjang-2 daftar yang memenuhi syarat ada. Ini jelas tidak terlalu efisien dalam hal panjang kode.

  • Menghasilkan partisi integer N dan kemudian menyaring memiliki 2 kelemahan utama: efisiensi panjang dan waktu. Untuk mengatasi masalah itu, saya pikir saya pertama kali akan datang dengan metode untuk menghasilkan hanya pasangan bilangan bulat (x,y) yang menjumlahkan ke N (tidak semua daftar panjang sewenang-wenang) dengan ketentuan bahwa kedua angka harus palindrom.

  • Tapi tetap saja, saya tidak puas dengan "cara klasik" tentang ini. Saya beralih pendekatan: daripada menghasilkan pasangan , mari kita fokus pada palindrom idividual . Dengan cara ini, seseorang dapat dengan mudah menghitung semua palindrom x bawah N , dan jika Nx juga palindrom, maka kita selesai.

Penjelasan Kode

2_ŒḂƇ⁺ṆƲ # - Tautan monadik atau Program lengkap. Argumen: n.
2 # - Mulai dari 2 * , temukan bilangan bulat n pertama yang memuaskan ...
 _ŒḂƇ⁺ṆƲ - ... tautan pembantu. Breakdown (panggil integer N saat ini):
    Ƈ - Saring. Menciptakan rentang [1 ... N] dan hanya menyimpannya yang ...
  ŒḂ - ... adalah palindrom. Contoh: 21 -> [1,2,3,4,5,6,7,8,9,11]
 _ - Kurangi masing-masing palindrom dari N. Contoh: 21 -> [20,19, ..., 12,10]
     ⁺ - Gandakan tautan sebelumnya (anggap seolah ada tambahan ŒḂƇ
            bukannya ⁺). Ini hanya menyimpan palindrom dalam daftar ini.
            Jika daftarnya tidak kosong, maka itu berarti kami telah menemukan pasangan (x, Nx) itu
            mengandung dua palindrom (dan jelas x + Nx = N sehingga mereka menjumlahkan ke N).
      Ṇ - TIDAK logis (kami sedang mencari bilangan bulat yang daftar ini kosong).
       Ʋ - Kelompokkan 4 tautan terakhir (pada dasarnya menjadikan _ŒḂƇ⁺Ṇ bertindak sebagai monad tunggal).

* Angka non-nol lainnya berfungsi, dalam hal ini.

Tuan Xcoder
sumber
7

Jelly , 11 byte

⁵ŻŒḂ€aṚ$EƲ#

Cobalah online!

Program lengkap kira-kira berfungsi seperti ini:

  1. Atur z ke input.
  2. Set x ke 10 .
  3. Set R untuk [] .
  4. Untuk setiap bilangan bulat k dari 0 hingga dan termasuk x , periksa apakah k dan x - k adalah palindromik.
  5. Jika semua elemen L sama (yaitu, jika semua pasangan yang mungkin dijumlahkan ke x memiliki kedua elemen palindromiknya, atau semua pasangan demikian memiliki paling banyak salah satu elemennya adalah palindromik), atur z ke z - 1 dan tambahkan x untuk R .
  6. Jika z = 0 , kembalikan R dan akhiri.
  7. Set x ke x + 1 .
  8. Lanjutkan ke langkah 4.

Anda mungkin curiga bahwa langkah 5 tidak benar-benar melakukan pekerjaan yang seharusnya. Kita seharusnya benar-benar tidak mengurangi z jika semua pasangan yang menjumlahkan x adalah palindromik. Namun, kami dapat membuktikan bahwa ini tidak akan pernah terjadi:

Mari kita pertama memilih integer k sehingga 10kx . Kami selalu dapat melakukannya, karena, pada langkah 2, kami menginisialisasi x menjadi 10 .

Jika k bukan palindrome, maka kita memiliki pasangan (k,xk) , di mana k+(xk)=x , oleh karena itu tidak semua pasangan memiliki dua palindrom.

Sebaliknya, jika k adalah palindrom, maka kita dapat membuktikan bahwa k1 bukanlah palindrom. Biarkan digit pertama dan terakhir k menjadi DF dan DL masing-masing. Karena k adalah palindrome, DF=DL>0 . Biarkan digit pertama dan terakhir k1 masing-masing menjadi DF dan DLKarena DL>0 , DL=DF1DF . Karenanya,k1 bukanlah palindrom, dan kami memiliki pasangan(k1,x(k1)) , di mana(k1)+(x(k1))=k1+xk+1=x .

Kami menyimpulkan bahwa, jika kita mulai dengan menetapkan x ke nilai yang lebih besar dari atau sama dengan 10 , kita tidak akan pernah memiliki semua pasangan bilangan bulat non-negatif yang dijumlahkan x menjadi pasangan palindrom.

Erik the Outgolfer
sumber
Ah, kalahkan juga - pertama n syarat menghemat 1 byte (saya memilih STDIN danŻŒḂ€aṚ$Ṁ¬µ#
Jonathan Allan
@Jonathan Allan Oh LOL tidak mengharapkan itu. Bagaimanapun, seseorang mengalahkan kita berdua. : D
Erik the Outgolfer
(10,x-10)10
11
3

Retina , 135 102 byte

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

Cobalah online! Terlalu lambat untuk n10 atau lebih. Penjelasan:

K`0

Mulailah dengan mencoba 0.

"$+"{

Ulangi nkali.

0L$`\d+
*__

Ubah nilai uji coba saat ini menjadi unary dan tambahkan.

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

Buat semua pasangan bilangan bulat non-negatif yang menjumlahkan nilai uji coba baru.

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

Ulangi sementara ada setidaknya satu pasangan yang mengandung dua bilangan palindromik.

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

Tambahkan dan kembangkan nilai uji coba lagi.

0L`\d+

Ekstrak nilai akhir.

Neil
sumber
3

Haskell, 68 67 63 byte

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

Mengembalikan urutan yang tak terbatas.

Kumpulkan semua di nmana aatau n-abukan palindrome untuk semua a <- [0..n].

Cobalah online!

nimi
sumber
3

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

-3 byte terima kasih kepada @NahuelFouilleul

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

Cobalah online!

Catatan: anybisa diganti dengan grepdan menghindari -Msaklar baris perintah, tetapi di bawah aturan penilaian saat ini, itu akan menelan biaya satu byte lagi.

Xcali
sumber
perbaikan kecil, -3bytes , menggunakan while bukan redo
Nahuel Fouilleul
Dan mengambil satu lagi dari itu dengan menghilangkan +setelah while.
Xcali
3

R , 115 111 byte

-4 Terima kasih kepada 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]

Cobalah online!

Sebagian besar pekerjaan dikemas ke dalam argumen fungsi untuk menghapus {}panggilan fungsi multi-pernyataan, dan untuk mengurangi tanda kurung yang diperlukan dalam mendefinisikan objekr

Strategi dasarnya adalah menemukan semua palindrom hingga batas yang diberikan (termasuk 0), menemukan semua jumlah berpasangan, dan kemudian mengambil angka ke-n tidak dalam output itu.

Batasan n*1000dipilih murni dari tebakan yang berpendidikan, jadi saya mendorong siapa pun untuk membuktikan / membuktikannya sebagai pilihan yang valid.

r=0:(n*1e3)mungkin dapat ditingkatkan dengan ikatan yang lebih efisien.

Map(paste,Map(rev,strsplit(a,"")),collapse="")robek dari jawaban Markus di sini , dan sangat pintar bagi saya.

r[!r%in%outer(p,p,'+')][n]membaca sedikit tidak efisien untuk saya.

Kriminal kriminal
sumber
1
111 byte hanya dengan mengatur ulang beberapa hal.
Giuseppe
1

J , 57/60 byte

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

Cobalah online!

Versi yang ditautkan menambahkan 3 byte dengan total 60 untuk disimpan sebagai fungsi yang dapat dipanggil footer.

Dalam REPL, ini dihindari dengan menelepon langsung:

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

Penjelasan

Struktur umum adalah teknik ini dari jawaban oleh 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

Ini menghemat beberapa byte daripada teknik perulangan asli saya, tetapi karena fungsi inti adalah upaya pertama saya untuk menulis J, ada kemungkinan masih banyak yang dapat ditingkatkan.

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.
0xfordcomma
sumber
Itu format lama milik saya, menggabungkan trik lain yang saya pelajari sejak saat itu menghasilkan solusi 41 char:1&(_:1&((e.((*&(-:|.)&":"0>:)&i.-))+])+)*
miles
1

05AB1E , 15 12 byte

°ÝDʒÂQ}ãOKIè

-3 byte terima kasih kepada @Grimy .

Diindeks 0.
Sangat lambat, sehingga waktu habis untuk sebagian besar kasus uji.

Cobalah secara online atau verifikasi beberapa kasus pertama dengan menghapus .

Jauh lebih cepat versi 15 byter sebelumnya:

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

1-diindeks.

Cobalah secara online atau hasilkan yang pertamannilai-nilai .

Penjelasan:

°Ý              # 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)
Kevin Cruijssen
sumber
1
12: °LDʒÂQ}ãOKIè(mungkin ada batas atas yang lebih baik dari 10 ^ x untuk kecepatan). Saya kira ∞DʒÂQ}ãOKsecara teknis angka 9, tetapi sudah habis sebelum output pertama.
Grimmy
@Grimy Tidak yakin apakah produk cartesian bekerja dengan malas di daftar tak terbatas. Bagaimanapun, untuk 12-byter, sayangnya itu tidak benar. Itu memang menyaring bilangan bulat yang dapat dibentuk dengan menjumlahkan 2 palindrom, tetapi bukan bilangan bulat yang merupakan palindrom sendiri. Urutan Anda (tanpa trailing ) seperti: [1,21,32,43,54,65,76,87,98,111,131,141,151,...]tetapi seharusnya seperti [*,21,32,43,54,65,76,87,98,201,1031,1041,1051,1052,...](yang pertama 1/ *dapat diabaikan karena kami menggunakan input 1-diindeks).
Kevin Cruijssen
1
@Grimy Hmm, saya kira perbaikan lurus ke depan adalah mengubah daftar berbasis 1 menjadi berbasis L0 .. :)
Kevin Cruijssen
0

Merah , 142 byte

func[n][i: 1 until[i: i + 1 r: on repeat k i[if all[(to""k)= reverse
to""k(s: to""i - k)= reverse copy s][r: off break]]if r[n: n - 1]n < 1]i]

Cobalah online!

Mengembalikan istilah ke-n, 1-diindeks

Galen Ivanov
sumber
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

Cobalah online!

Melawan pemeriksaan palindrom disimpan 2 byte :)

Untuk referensi, cek positif langsung ke depan (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
movatica
sumber
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

Apa kata untuk break the loop? Sepertinya itu ": pergi", kan? {k≡⌽k←⍕⍵}di p adalah tes untuk palindrome. Fungsi di atas dalam loop menyimpan semua palindrome yang ditemukan di set P, jika untuk beberapa elemen w dari P sedemikian rupa sehingga iw ada di P juga ini berarti bahwa i tidak benar dan kita memiliki kenaikan i. Hasil:

  f 1
21
  f 2
32
  f 10
1031
  f 16
1061
  f 40
1103
  f 1000
4966
  f 1500
7536
RosLuP
sumber