Penyisipan minimum untuk membuat palindrome

15

Hari ini Anda akan melakukan tantangan palindrom lain!

Jadi, tugas Anda hari ini adalah mengambil string, dan menentukan jumlah huruf minimum yang diperlukan untuk memasukkannya menjadi palindrome.

Sebagai contoh, mari kita ambil string fishes.

Dalam hal ini, case cara terbaik adalah menambahkan h if, sehingga hasilnya adalah 3.

fishe s
     h if
---------
fishehsif

Sekarang mari kita coba codegolf. Karena ada yang berulang o, kita bisa melakukan:

  codeg  o lf
fl     ed c
-------------
flcodegedoclf

untuk mendapatkan hasil 5.

Uji kasus

ppcg -> 2
codegolf -> 5
palindrome -> 9
stackexchange -> 8
programmingpuzzlesandcodegolf -> 20
Oliver Ni
sumber
1
Terkait , dengan insersi hanya terjadi di sebelah kanan.
xnor
2
Wow, sekali lagi, saya punya ide tantangan yang tepat ini dua hari yang lalu ... tetapi sistem penilaian akan menjadi panjang kode Anda + output ketika kodenya dijalankan sendiri. (yaitu kode adalah ppcg, skor 4 + 2 = 6)
ETHproduksi
5
Ini adalah tantangan yang bagus, tetapi saya lebih suka jika tantangan topik yang sama lebih dijabarkan. Ada banyak palindrome dalam beberapa hari terakhir.
xnor
1
Mungkin sulit untuk membuktikan bahwa program yang diberikan benar-benar menemukan jumlah huruf minimum
edc65

Jawaban:

3

Pyth, 10 byte

test suite.

l.-Qe@y_Qy

         y   All subsequences of the input (implicit), sorted by length
      y_Q    All subsequences of the reversed input, sorted by length
     @       Their setwise intersection: the common subsequences
    e        Last element: the longest common subsequence
 .-Q         Remove it bagwise from the input: the letters not in this LCS
l            The length of that

Ada beberapa penokohan yang setara dari nilai yang kami kejar:

  • Sisipan paling sedikit diperlukan untuk membuat palindrome
  • Penghapusan paling sedikit diperlukan untuk membuat palindrome
  • Setengah jumlah operasi hapus atau masukkan yang diperlukan untuk mengubah string menjadi terbalik
  • Panjang input dengan urutan palindromik terpanjang dihapus
  • Panjang input, menghapus urutan umum terpanjang antara itu dan kebalikannya. (Kode ini menggunakan yang ini.)

Gagasan umum adalah "kerangka" huruf dalam input yang cocok dengan huruf input dalam produk akhir.

  codeg  o lf
   *  *  *
fl o  gedoc 

flcodegedoclf

Kerangka ini selalu palindrom, dengan huruf yang cocok dengan rekan-rekan mereka yang terbalik. Setiap huruf non-kerangka tidak cocok dan harus memiliki pasangannya yang dimasukkan.

Alternatif dengan panjang yang sama menggunakan kondisi keempat, panjang input dikurangi panjang palindromik berikutnya.

l.-Qef_ITy

Tautan ke ruang uji.

Bagian yang berbeda adalah

f_ITy

    y   All subsequences of the input (implicit), sorted by length.
f       Filtered on:
 _IT     being invariant under reversal, i.e. a palindrome

Untuk keduanya, alih-alih menghapus urutan palindrom dari input dan mengambil panjang, kita bisa mengurangi panjangnya dari panjang input. Salah satu biaya 4 bytes: -lQlvs l.-Q.

Tidak
sumber
3

Python, 112 byte

d=lambda x,l,h:0if h<l else d(x,l+1,h-1)if x[l]==x[h]else-~min(d(x,l+1,h),d(x,l,h-1));e=lambda x:d(x,0,len(x)-1)

Sangat tidak efisien.

Cobalah online!Anda harus menunggu sebentar untuk menyelesaikan kasus terakhir.

Telepon dengan e(<string>, 0, <length of string - 1>) , seperti e ("ikan", 0, 5) `.

Tidak dikelompokkan (semacam) dengan penjelasan:

def minInsert(x, l, h):                # Declare func, arugments for x, l, h       # d=lambda x,l,h:
  if l >= h:                           # If l is the same or past h                #                 if h<l
    return 0                           #     then return 0                         #                0
  elif x[l] == x[h]:                   # If first and last character are the same  #                        else             if x[l]==x[h]
    return minInsert(x, l + 1, h - 1)  #     then return the min w/o first & last  #                             d(x,l+1,h-1)
  else:                                # If not, we shave off a character          #                                                      else
    a = minInsert(x, l, h - 1)         #     (last one)                            #                                                                d(x,l+1,h)
    b = minInsert(x, l + 1, h)         #     (first one)                           #                                                                           d(x,l,h-1)
    return min(a, b) + 1               #     and add one for the char we took off  #                                                          -~min(          ,          )
Oliver Ni
sumber
3
Mendapatkan input tambahan dengan data (panjang daftar) secara hukum tidak sah. Juga bukan input 0, tetapi Anda bisa memperbaikinya dengan argumen default l=0.
xnor
@xnor Tetap .---
Oliver Ni
@ edc65 saya etited.
Oliver Ni
2

05AB1E , 11 byte

Menggunakan pengodean CP-1252 .

Âæsæäg¹g-Ä

Cobalah online! atau sebagai Test suite

Penjelasan

              # implicit input
             # push a reversed copy
 æ            # compute powerset of the reversed string
  sæ          # compute powerset of the string
    äg       # get length of the longest common subset
      ¹g-     # subtract the length of the original string
         Ä    # take absolute value
Emigna
sumber
2

Brachylog , 9 byte

⊆P↔P;?lᵐ-

Cobalah online!

Tantangan ini sangat membutuhkan jawaban Brachylog v2, karena penyisipan palindromisasi sangat intuitif dalam bahasa itu.

Penjelasan

⊆P↔Pbenar-benar apa yang dilakukan palindromisasi dengan memasukkan (lihat contoh ini )

⊆P           P is an ordered superset of the input
 P↔P         P reversed is P (i.e. P is a palindrome)
   P;?lᵐ     Compute the length of both P and the input
        -    Subtraction
Fatalisasi
sumber
1

C, 89 121 byte

#define g(a) f(a,a+strlen(a)-1)
f(char*a,char*b){return a>=b?0:*a-*b?f(a+1,b)<f(a,b-1)?f(++a,b)+1:f(a,--b)+1:f(++a,--b);}

Pelabuhan Oliver yang tak tahu malu jawaban , tidak bisa memikirkan solusi yang lebih pendek.

gpanggilan fdengan pointer ke char pertama dan terakhir dari string (char terakhir adalah bagian dari string, bukan '\0'). Mendapat lebih tidak efisien karena fdipanggil dua kali untukmin kasus ini.

Tidak Disatukan:

f(char*a,char*b){
 return a>=b ? 0 :
   *a-*b ?    //if the pointed chars are not the same
     f(a+1,b)<f(a,b-1) ? f(a+1,b)+1 : f(a,b-1)+1    //min(f..,f..)+1
   : f(a+1,b-1);  //if they were the same, make it more narrow
 }

Pemakaian:

int main(){
 char s[]="palindrome";
 printf("%d\n",g(s));
}
Karl Napf
sumber
2
Mendapatkan input tambahan dengan data tidak sah secara default
edc65
1

Brachylog v1 , 13 byte

,IrIs?:I:lar-

Cobalah online!

Anda dapat memeriksa palindrom yang ditemukannya dengan kode ini .

Penjelasan

Saya hampir terkejut bahkan ini berhasil, melihat betapa sederhananya itu.

,IrI             I reversed is I (i.e. I is a palindrome)
   Is?           The Input is an ordered subset of I
     ?:I:la      The list [length(Input), length(I)]
           r-    Output = length(I) - length(Input)

Ini dijamin untuk menemukan palindrome terkecil karena IrI akan menghasilkan string yang semakin panjang ketika mundur, mulai dari string kosong.

Ini tidak cukup efisien untuk menghitung test case terakhir pada TIO, karena penggunaan s - Ordered subset.

Fatalisasi
sumber
0

Batch, 234 232 byte

@echo off
set n=99
call:l 0 %1
echo %n%
exit/b
:g
set/am=%1
if %m% lss %n% set/an=m
exit/b
:l
if "%2"=="" goto g
set s=%2
if %s:~,1%==%s:~-1% call:l %1 %s:~1,-1%&exit/b
call:l %1+1 %s:~1%
set s=%2
call:l %1+1 %s:~,-1%

Berfungsi secara rekursif mencoba memasukkan karakter yang tidak cocok di kedua ujungnya, jadi sangat lambat (saya tidak mencoba test case terakhir). Batas rekursi berarti bahwa ini hanya berfungsi untuk panjang string yang terbatas, sehingga 99agak arbitrer. Saya harus menggunakan callparameter sebagai variabel lokal karena saya tidak bisa setlocalbekerja untuk saya, yang berarti %1parameter ke :lsubrutin adalah ekspresi yang mengevaluasi jumlah penyisipan yang dilakukan sejauh ini.

Neil
sumber