Inserimenti minimi per realizzare palindromo


15

Oggi farai un'altra sfida palindromo!

Quindi, il tuo compito oggi è quello di prendere una stringa e determinare la quantità minima di lettere da inserire per trasformarla in un palindromo.

Ad esempio, prendiamo la stringa fishes.

In questo caso, il modo migliore sarebbe aggiungere h if, quindi il risultato sarebbe 3.

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

Ora proviamo con codegolf. Dal momento che c'è un ripetuto o, possiamo semplicemente fare:

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

per ottenere un risultato di 5.

Casi test

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

1
Correlati , con inserimenti che avvengono solo a destra.
xnor

2
Wow, ancora una volta, ho avuto questa esatta idea di sfida due giorni fa ... ma il sistema di punteggio sarebbe stato la lunghezza del tuo codice + l'output quando il suo codice viene eseguito da solo. (cioè il codice è ppcg, il punteggio è 4 + 2 = 6)
ETHproductions

5
Questa è una bella sfida, ma preferirei che le sfide dello stesso argomento fossero più distanziate. C'è stato un sacco di palindromi negli ultimi due giorni.
xnor

1
Potrebbe essere difficile dimostrare che un determinato programma trova davvero la quantità minima di lettere
edc65

Risposte:


3

Pyth, 10 byte

suite di test.

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

Esistono alcune caratterizzazioni equivalenti del valore che stiamo cercando:

  • Il minor numero di inserzioni necessario per realizzare un palindromo
  • Il minor numero di eliminazioni necessarie per creare un palindromo
  • La metà del numero di operazioni di eliminazione o inserimento necessarie per trasformare la stringa al suo contrario
  • La lunghezza dell'input con la sua sottosequenza palindromica più lunga rimossa
  • La lunghezza dell'input, rimuovendo la sottosequenza comune più lunga tra esso e il suo contrario. (Il codice usa questo.)

L'idea comune è lo "scheletro" delle lettere nell'input che sono abbinate alle lettere dell'input nel prodotto finale.

  codeg  o lf
   *  *  *
fl o  gedoc 

flcodegedoclf

Questo scheletro è sempre un palindromo, con lettere corrispondenti alle loro controparti invertite. Ogni lettera non scheletro non ha eguali e deve avere la sua controparte inserita.

Un'alternativa della stessa lunghezza utilizza invece la quarta condizione, la lunghezza dell'input meno la lunghezza della sua sottosequenza palindromica più lunga

l.-Qef_ITy

Link alla suite di test.

La parte che è diversa è

f_ITy

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

Per entrambi, invece di rimuovere la sottosequenza palindromica dall'input e prendere la lunghezza, potremmo invece sottrarre la sua lunghezza dalla lunghezza dell'input. Uno dei due costi: 4 byte -lQlvs l.-Q.


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)

Molto inefficiente.

Provalo online! Devi aspettare un minuto affinché l'ultimo caso finisca.

Chiama con e(<string>, 0, <length of string - 1>), come e ("pesci", 0, 5) `.

Ungolfed (sorta di) con spiegazione:

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
Ottenere un input aggiuntivo con i dati (la lunghezza dell'elenco) non è legale per impostazione predefinita. Né è l'input di 0, ma è possibile risolverlo con un argomento predefinito l=0.
xnor

@xnor Fixed .---
Oliver Ni

@ edc65 ho scritto.
Oliver Ni,

2

05AB1E , 11 byte

Utilizza la codifica CP-1252 .

Âæsæäg¹g-Ä

Provalo online! o come una suite di test

Spiegazione

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

⊆P↔P;?lᵐ-

Provalo online!

Questa sfida aveva davvero bisogno di una risposta Brachylog v2, poiché la palindromizzazione dell'inserimento è così intuitiva in quella lingua.

Spiegazione

⊆P↔Pè davvero ciò che fa palindromizzazione per inserimento (vedi questo esempio )

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

Il porto spudorato della risposta di Oliver , non riusciva a pensare a nessuna soluzione più breve.

gchiama fcon il puntatore al primo e all'ultimo carattere di una stringa (l'ultimo carattere fa parte della stringa, non il '\0'). Diventa ancora più inefficiente perché fviene chiamato due volte per il mincaso.

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
 }

Uso:

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

2
Ottenere un input aggiuntivo con i dati non è legale per impostazione predefinita
edc65,

1

Brachylog v1 , 13 byte

,IrIs?:I:lar-

Provalo online!

Puoi controllare i palindromi che trova con questo codice .

Spiegazione

Sono quasi sorpreso che anche questo funzioni, visto quanto sia ridicolmente semplice.

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

Questo è garantito per trovare il palindromo più piccolo perché IrIgenererà stringhe di lunghezza crescente durante il backtracking, a partire dalla stringa vuota.

Questo non è abbastanza efficiente per calcolare l'ultimo caso di test su TIO, a causa dell'uso di s - Ordered subset.


0

Lotto, 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%

Funziona cercando in modo ricorsivo di inserire caratteri non corrispondenti su entrambe le estremità, molto lentamente (non ho provato l'ultimo caso di test). I limiti di ricorsione significano che questo funziona solo per una lunghezza di stringa limitata, quindi il99 è alquanto arbitrario. Devo usare i callparametri come variabili locali in quanto non sono riuscito setlocala lavorare per me, il che significa che il %1parametro per la :lsubroutine è un'espressione che valuta il numero di inserimenti effettuati finora.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.