Palindrom yapmak için minimum eklemeler


15

Bugün başka bir palindrom mücadelesi yapacaksınız!

Bu nedenle, bugünkü göreviniz bir dize almak ve onu bir palindrom haline getirmek için eklemek için gereken minimum harf miktarını belirlemektir.

Örneğin, dizeyi ele alalım fishes.

Bu durumda, en iyi yol eklemek olacaktır h if, bu nedenle sonuç 3 olacaktır.

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

Şimdi deneyelim codegolf. Tekrarlanan bir şey olduğu için oşunları yapabiliriz:

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

sonuç almak için 5.

Test senaryoları

ppcg -> 2
codegolf -> 5
palindrome -> 9
stackexchange -> 8
programmingpuzzlesandcodegolf -> 20

1
İlgili , sadece sağ tarafta eklemeler ile.
xnor

2
Vay be, yine, iki gün önce bu tam bir meydan okuma fikri vardı ... ama puanlama sistemi kendi kodu çalıştırıldığında kodu + çıkış uzunluğu olurdu. (yani kod ppcg, skor 4 + 2 = 6)
ETHproductions

5
Bu güzel bir meydan okuma, ancak aynı konudaki meydan okumaların daha aralıklı olmasını tercih ederim. Son birkaç gündür çok palindrom var.
xnor

1
Belirli bir programın gerçekten minimum miktarda harf bulduğunu kanıtlamak zor olabilir
edc65

Yanıtlar:


3

Pyth, 10 bayt

test odası.

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

Ardarda olduğumuz değerin birkaç eşdeğer karakterizasyonu var:

  • Palindrom yapmak için gereken en az ekleme
  • Palindrom yapmak için gereken en az silme
  • Dizeyi tersine dönüştürmek için gereken silme veya ekleme işlemlerinin yarısı
  • En uzun palindromik dizisi kaldırılmış olarak girdinin uzunluğu
  • Girdinin uzunluğu, tersi ve tersi arasındaki en uzun ortak diziyi kaldırarak. (Kod bunu kullanır.)

Ortak fikir, girişteki harflerin nihai üründeki giriş harfleriyle eşleşen "iskeleti" dir.

  codeg  o lf
   *  *  *
fl o  gedoc 

flcodegedoclf

Bu iskelet her zaman bir palindrom olup, harfleri tersine karşılık gelen harflerle eşleşir. İskelet olmayan her harf eşleşmez ve karşılığının eklenmesi gerekir.

Aynı uzunlukta bir alternatif bunun yerine dördüncü koşulu kullanır, girişin uzunluğu eksi en uzun palindromik dizisinin uzunluğunu ekler

l.-Qef_ITy

Test takımına bağlantı.

Farklı olan kısım

f_ITy

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

Her ikisi için de, palindromik diziyi girişten çıkarmak ve uzunluğu almak yerine, uzunluğunu girişin uzunluğundan çıkarabiliriz. Ya bir maliyeti 4 bayt: -lQlvs l.-Q.


3

Python, 112 bayt

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)

Çok verimsiz.

Çevrimiçi deneyin! Son vakanın bitmesi için bir dakika beklemelisin.

e(<string>, 0, <length of string - 1>)E ("balıklar", 0, 5) ` ile çağırın .

Açıklanamayan (bir çeşit) açıklama:

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(          ,          )

3
Verilerle (liste uzunluğu) fazladan girdi almak varsayılan olarak yasal değildir. 0 girişi de yoktur, ancak bunu varsayılan bir argümanla düzeltebilirsiniz l=0.
xnor

@xnor Sabit.
Oliver Ni

@ edc65 Ben etited.
Oliver Ni

2

05AB1E , 11 bayt

CP-1252 kodlamasını kullanır .

Âæsæäg¹g-Ä

Çevrimiçi deneyin! veya Test takımı olarak

açıklama

              # 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

2

Brachylog , 9 bayt

⊆P↔P;?lᵐ-

Çevrimiçi deneyin!

Ekleme palindromizasyonu o dilde çok sezgisel olduğundan, bu meydan okuma gerçekten bir Brachylog v2 cevabına ihtiyaç duyuyordu.

açıklama

⊆P↔Pgerçekten ekleme ile palindromizasyon nedir ( bu örneğe bakın )

⊆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

1

Cı, 89 121 bayt

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

Oliver'ın cevabının utanmaz limanı, daha kısa bir çözüm düşünemedi.

gçağıran fbirinci ve bir dizenin son char pointer ile (son karakter dizesinin parçası değildir '\0'). Dava fiçin iki kez çağrıldığı için daha da verimsiz olur min.

Ungolfed:

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
 }

Kullanımı:

int main(){
 char s[]="palindrome";
 printf("%d\n",g(s));
}


1

Brachylog v1 , 13 bayt

,IrIs?:I:lar-

Çevrimiçi deneyin!

Buldukları palindromları bu kodla kontrol edebilirsiniz .

açıklama

Bunun ne kadar gülünç derecede basit olduğunu görerek işe yaradığına neredeyse şaşırıyorum.

,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)

Bu, en küçük palindromu bulması garanti edilir, çünkü IrIboş takip dizisinden başlayarak geri izleme sırasında artan uzunlukta dizeler üretecektir.

Bu, kullanımı nedeniyle TIO'daki son test durumunu hesaplamak için yeterince verimli değildir s - Ordered subset.


0

Toplu, 234232 bayt

@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%

Her iki uçta da eşleşmeyen karakterler eklemeye çalışarak çalışır, çok yavaştır (son test senaryosunu denemedim). Özyineleme sınırları, bunun yalnızca sınırlı bir dize uzunluğu için çalıştığı anlamına gelir, bu nedenle 99biraz keyfi. callParametreleri yerel değişkenler olarak benim setlocaliçin işe alamadım olarak kullanmak zorundayım , yani alt rutine %1parametre :lşu ana kadar yapılan ekleme sayısını değerlendiren bir ifadedir.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.