Minimale Insertionen für Palindrom

15

Heute machst du eine weitere Palindrom-Herausforderung!

Ihre heutige Aufgabe ist es also, eine Zeichenfolge zu nehmen und die Mindestanzahl an Buchstaben zu bestimmen, die zum Einfügen erforderlich sind, um sie in ein Palindrom zu verwandeln.

Nehmen wir zum Beispiel den String fishes.

In diesem Fall wäre das Hinzufügen der beste Weg h if, das Ergebnis wäre also 3.

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

Jetzt versuchen wir es mit codegolf. Da es eine Wiederholung gibt o, können wir einfach tun:

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

um ein Ergebnis von 5 zu erhalten.

Testfälle

ppcg -> 2
codegolf -> 5
palindrome -> 9
stackexchange -> 8
programmingpuzzlesandcodegolf -> 20
Oliver Ni
quelle
1
Verwandte , mit Einfügungen nur auf der rechten Seite.
5.
2
Wow, vor zwei Tagen hatte ich genau diese Herausforderung ... aber das Bewertungssystem wäre die Länge Ihres Codes + die Ausgabe, wenn sein Code durch sich selbst ausgeführt wird. (dh der Code lautet ppcg, die Punktzahl ist 4 + 2 = 6)
ETHproductions
5
Dies ist eine schöne Herausforderung, aber ich würde es vorziehen, wenn Herausforderungen, die das gleiche Thema betreffen, weiter auseinander liegen. In den letzten Tagen gab es viel Palindrom.
5.
1
Es kann schwierig sein zu beweisen, dass ein bestimmtes Programm wirklich die Mindestanzahl von Buchstaben findet
edc65

Antworten:

3

Pyth, 10 Bytes

Testsuite.

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

Es gibt ein paar äquivalente Charakterisierungen des Wertes, den wir suchen:

  • Die wenigsten Einfügungen waren erforderlich, um ein Palindrom herzustellen
  • Die wenigsten Deletionen waren nötig, um ein Palindrom herzustellen
  • Die Hälfte der Lösch- oder Einfügeoperationen, die zum Umwandeln der Zeichenfolge in die umgekehrte Reihenfolge erforderlich sind
  • Die Länge der Eingabe, deren längste palindromische Teilsequenz entfernt wurde
  • Die Länge der Eingabe, wobei die längste gemeinsame Teilsequenz zwischen ihr und ihrer Umkehrung entfernt wird. (Der Code verwendet diesen.)

Die übliche Idee ist das "Skelett" von Buchstaben in der Eingabe, die mit den Buchstaben der Eingabe im Endprodukt übereinstimmen.

  codeg  o lf
   *  *  *
fl o  gedoc 

flcodegedoclf

Dieses Skelett ist immer ein Palindrom mit Buchstaben, die mit den umgekehrten Gegenstücken übereinstimmen. Jeder Buchstabe, der kein Gerüst ist, ist nicht passend und muss sein Gegenstück enthalten.

Eine Alternative gleicher Länge verwendet stattdessen die vierte Bedingung, die Länge der Eingabe abzüglich der Länge ihrer längsten palindromischen Untersequenz

l.-Qef_ITy

Link zur Testsuite.

Der Teil, der anders ist, ist

f_ITy

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

Für beide können wir, anstatt die palindromische Subsequenz von der Eingabe zu entfernen und die Länge zu nehmen, stattdessen ihre Länge von der Länge der Eingabe subtrahieren. Entweder man Kosten 4 Bytes: -lQlvs l.-Q.

xnor
quelle
3

Python, 112 Bytes

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)

Sehr ineffizient.

Probieren Sie es online! Sie müssen eine Minute warten, bis der letzte Fall abgeschlossen ist.

Rufen Sie mit e(<string>, 0, <length of string - 1>), wie e ("Fische", 0, 5) `.

Ungolfed mit Erklärung:

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
quelle
3
Das Abrufen einer zusätzlichen Eingabe mit Daten (der Listenlänge) ist standardmäßig nicht zulässig. Weder ist die Eingabe von 0, aber Sie könnten das mit einem Standardargument beheben l=0.
5.
@xnor Fixed .---
Oliver Ni
@ edc65 habe ich geätzt.
Oliver Ni
2

05AB1E , 11 Bytes

Verwendet die CP-1252- Codierung.

Âæsæäg¹g-Ä

Probieren Sie es online! oder als Testsuite

Erläuterung

              # 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
quelle
2

Brachylog , 9 Bytes

⊆P↔P;?lᵐ-

Probieren Sie es online!

Diese Herausforderung erforderte wirklich eine Brachylog v2-Antwort, da die Palindromisierung der Einfügung in dieser Sprache so intuitiv ist.

Erläuterung

⊆P↔PWas bedeutet Palindromisierung durch Insertion (siehe dieses Beispiel ) ?

⊆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
Tödlich
quelle
1

C, 89 121 Bytes

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

Schamlose Portierung von Olivers Antwort, könnte sich keine kürzere Lösung vorstellen.

gruft fmit dem Zeiger auf das erste und das letzte Zeichen eines Strings auf (das letzte Zeichen ist Teil des Strings, nicht das '\0'). Wird noch ineffizienter, weil fzweimal für den minFall aufgerufen wird.

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
 }

Verwendung:

int main(){
 char s[]="palindrome";
 printf("%d\n",g(s));
}
Karl Napf
quelle
2
Das
Abrufen
1

Brachylog v1 , 13 Bytes

,IrIs?:I:lar-

Probieren Sie es online!

Mit diesem Code können Sie die gefundenen Palindrome überprüfen .

Erläuterung

Ich bin fast überrascht, dass dies sogar funktioniert, wenn man sieht, wie lächerlich einfach es ist.

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

Dies ist garantiert, um das kleinste Palindrom zu finden, da IrIZeichenfolgen mit zunehmender Länge beim Zurückverfolgen erzeugt werden, beginnend mit der leeren Zeichenfolge.

Dies ist aufgrund der Verwendung von nicht effizient genug, um den letzten Testfall unter TIO zu berechnen s - Ordered subset.

Tödlich
quelle
0

Batch, 234 232 Bytes

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

Arbeitet, indem rekursiv versucht wird, nicht übereinstimmende Zeichen an beiden Enden einzufügen, also sehr langsam (ich habe den letzten Testfall nicht ausprobiert). Rekursionslimits bedeuten, dass dies ohnehin nur für eine begrenzte Stringlänge funktioniert, was also 99etwas willkürlich ist. Ich muss callParameter als lokale Variablen verwenden, da ich setlocalfür mich nicht arbeiten konnte. Dies bedeutet, dass der %1Parameter für die :lUnterroutine ein Ausdruck ist, der die Anzahl der bisher ausgeführten Einfügungen ermittelt.

Neil
quelle