Inserções mínimas para fazer palíndromo

15

Hoje você estará fazendo outro desafio palíndromo!

Portanto, sua tarefa hoje é pegar uma string e determinar a quantidade mínima de letras necessária para inserir para transformá-la em um palíndromo.

Por exemplo, vamos pegar a string fishes.

Nesse caso, a melhor maneira seria adicionar h if, portanto o resultado seria 3.

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

Agora vamos tentar com codegolf. Uma vez que existe uma repetiçãoo , podemos apenas fazer:

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

para obter um resultado de 5.

Casos de teste

ppcg -> 2
codegolf -> 5
palindrome -> 9
stackexchange -> 8
programmingpuzzlesandcodegolf -> 20
Oliver Ni
fonte
1
Relacionado , com inserções acontecendo apenas à direita.
Xnor
2
Uau, novamente, eu tive essa idéia exata de desafio há dois dias atrás ... mas o sistema de pontuação teria o tamanho do seu código + a saída quando o código fosse executado por si mesmo. (ou seja, o código é ppcg, a pontuação é 4 + 2 = 6)
ETHproductions
5
Esse é um bom desafio, mas eu preferiria que os desafios do mesmo tópico fossem mais espaçados. Houve muitos palíndromo nos últimos dias.
Xnor
1
Poderia ser difícil provar que um determinado programa realmente encontra a mínima quantidade de cartas
edc65

Respostas:

3

Pitão, 10 bytes

suíte de teste.

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

Existem algumas caracterizações equivalentes do valor que buscamos:

  • O menor número de inserções necessárias para fazer um palíndromo
  • O menor número de exclusões necessárias para criar um palíndromo
  • Metade do número de operações de exclusão ou inserção necessárias para transformar a cadeia de caracteres em seu reverso
  • O comprimento da entrada com sua subsequência palindrômica mais longa removida
  • O comprimento da entrada, removendo a subsequência comum mais longa entre ela e seu reverso. (O código usa este.)

A idéia comum é o "esqueleto" das letras na entrada que correspondem às letras da entrada no produto final.

  codeg  o lf
   *  *  *
fl o  gedoc 

flcodegedoclf

Esse esqueleto é sempre um palíndromo, com letras correspondentes aos seus pares invertidos. Cada letra não esquelética é incomparável e deve ter sua contraparte inserida.

Uma alternativa de mesmo comprimento usa a quarta condição, o comprimento da entrada menos o comprimento de sua subsequência palindrômica mais longa

l.-Qef_ITy

Link para o conjunto de testes.

A parte que é diferente é

f_ITy

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

Para ambos, em vez de remover a subsequência palíndrica da entrada e pegar o comprimento, poderíamos subtrair seu comprimento do comprimento da entrada. Qualquer um dos dois custos 4 bytes: -lQlvs l.-Q.

xnor
fonte
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)

Muito ineficiente.

Experimente online! Você precisa esperar um minuto para que o último caso termine.

Ligue com e(<string>, 0, <length of string - 1>), como e ("peixes", 0, 5) `.

Ungolfed (tipo de) com explicação:

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
fonte
3
Obter uma entrada extra com dados (o tamanho da lista) não é legal por padrão. A entrada também não é 0, mas você pode corrigir isso com um argumento padrão l=0.
Xnor
@xnor Fixed .---
Oliver Ni
@ edc65 eu etitei.
Oliver Ni
2

05AB1E , 11 bytes

Usa a codificação CP-1252 .

Âæsæäg¹g-Ä

Experimente online! ou como conjunto de testes

Explicação

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

Braquilog , 9 bytes

⊆P↔P;?lᵐ-

Experimente online!

Esse desafio realmente precisava de uma resposta Brachylog v2, pois a palindromização de inserção é tão intuitiva nesse idioma.

Explicação

⊆P↔Pé realmente o que faz a palindromização por inserção (veja este exemplo )

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

Porto vergonhoso da resposta de Oliver , não conseguia pensar em nenhuma solução mais curta.

gchama fcom o ponteiro para o primeiro e o último caractere de uma string (o último char faz parte da string, não o '\0'). Fica ainda mais ineficiente porque fé chamado duas vezes para o 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));
}
Karl Napf
fonte
2
Obtendo uma entrada extra com dados não é legal por padrão
edc65
1

Brachylog v1 , 13 bytes

,IrIs?:I:lar-

Experimente online!

Você pode verificar os palíndromos encontrados com este código .

Explicação

Estou quase surpreso que isso funcione, vendo como é ridiculamente simples.

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

É garantido que você encontre o menor palíndromo, pois IrIirá gerar seqüências de comprimento cada vez maior ao voltar atrás, começando pela sequência vazia.

Isso não é eficiente o suficiente para calcular o último caso de teste no TIO, devido ao uso de s - Ordered subset.

Fatalizar
fonte
0

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

Funciona tentando recursivamente inserir caracteres não correspondentes nas duas extremidades, de forma muito lenta (não tentei o último caso de teste). Limites de recursão significam que isso só funciona para um comprimento limitado de string, portanto 99é um tanto arbitrário. Eu tenho que usar callparâmetros como variáveis ​​locais, pois não consegui setlocaltrabalhar para mim, o que significa que o %1parâmetro para a :lsub-rotina é uma expressão que avalia o número de inserções feitas até agora.

Neil
fonte