Минимальные вставки для палиндрома

15

Сегодня вы будете делать еще один вызов палиндром!

Итак, ваша задача сегодня состоит в том, чтобы взять строку и определить минимальное количество букв, необходимых для вставки, чтобы превратить ее в палиндром.

Например, давайте возьмем строку fishes.

В этом случае лучший способ будет добавить h if, поэтому результат будет 3.

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

Теперь давайте попробуем с codegolf. Так как здесь повторяется o, мы можем просто сделать:

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

чтобы получить результат 5.

Контрольные примеры

ppcg -> 2
codegolf -> 5
palindrome -> 9
stackexchange -> 8
programmingpuzzlesandcodegolf -> 20
Оливер Ни
источник
1
Связанные , с вставками, только происходит справа.
xnor
2
Ух ты, опять же, у меня была точная идея вызова два дня назад ... но система подсчета очков была бы длиной твоего кода + выводом, когда его код проходил сам по себе. (то есть код ppcg, оценка 4 + 2 = 6)
ETHproductions
5
Это хороший вызов, но я бы предпочел, чтобы вызовы той же темы были более разнесенными. За последние пару дней было много палиндромов.
xnor
1
Может быть трудно доказать, что данная программа действительно находит минимальное количество букв
edc65

Ответы:

3

Pyth, 10 байт

тестирование.

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

Есть несколько эквивалентных характеристик значения, которое мы ищем:

  • Наименьшее количество вставок, необходимых для палиндрома
  • Наименьшее количество удалений, необходимых для создания палиндрома
  • Половина количества операций удаления или вставки, необходимых для преобразования строки в обратную
  • Длина ввода с удаленной самой длинной палиндромной подпоследовательностью
  • Длина входа, удаляя самую длинную общую подпоследовательность между ним и его обратным. (Код использует этот.)

Общая идея - «скелет» букв на входе, которые совпадают с буквами на входе в конечном продукте.

  codeg  o lf
   *  *  *
fl o  gedoc 

flcodegedoclf

Этот скелет всегда палиндром, с буквами, соответствующими их обратным аналогам. Каждые не скелетные буквы не имеют себе равных и должны иметь вставленный аналог.

Альтернатива той же длины вместо этого использует четвертое условие: длина входного сигнала минус длина его самой длинной палиндромной подпоследовательности

l.-Qef_ITy

Ссылка на набор тестов.

Часть, которая отличается

f_ITy

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

Для обоих, вместо удаления палиндромной подпоследовательности из ввода и взятия длины, мы могли бы вместо этого вычесть ее длину из длины ввода. Любой из них стоит 4 байта: -lQlпротив l.-Q.

XNOR
источник
3

Python, 112 байт

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)

Очень неэффективно.

Попробуйте онлайн! Вы должны подождать минуту, пока закончится последнее дело.

Позвоните e(<string>, 0, <length of string - 1>), как e ("рыбы", 0, 5) `.

Ungolfed (вроде) с объяснением:

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
Получение дополнительных данных с данными (длина списка) не разрешено по умолчанию. Также нет ввода 0, но вы можете исправить это с помощью аргумента по умолчанию l=0.
xnor
@xnor Исправлено .---
Оливер Ни
@ edc65 Я это сделал.
Оливер Ни
2

05AB1E , 11 байт

Использует кодировку CP-1252 .

Âæsæäg¹g-Ä

Попробуйте онлайн! или как тестовый набор

объяснение

              # 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
источник
2

Брахилог , 9 байт

⊆P↔P;?lᵐ-

Попробуйте онлайн!

Эта задача действительно нуждалась в ответе Brachylog v2, так как палиндромизация при вставке настолько интуитивна в этом языке.

объяснение

⊆P↔Pна самом деле это то, что делает палиндромизацию путем вставки (см. этот пример )

⊆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
Fatalize
источник
1

C 89 121 байт

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

Бесстыдный порт ответа Оливера , не мог придумать ни одного более короткого решения.

gвызовы fс указателем на первый и последний символ строки (последний символ является частью строки, а не символом '\0'). Становится еще более неэффективным, потому что fвызывается два раза для 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
 }

Использование:

int main(){
 char s[]="palindrome";
 printf("%d\n",g(s));
}
Карл Напф
источник
2
Получение дополнительных данных с данными по умолчанию
недопустимо
1

Brachylog v1 , 13 байт

,IrIs?:I:lar-

Попробуйте онлайн!

Вы можете проверить найденные палиндромы с помощью этого кода .

объяснение

Я почти удивлен, что это даже работает, видя, как это смехотворно просто.

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

Это гарантированно найдет наименьший палиндром, потому IrIчто при возврате будет генерировать строки увеличивающейся длины, начиная с пустой строки.

Это недостаточно эффективно для вычисления последнего контрольного примера на TIO из-за использования s - Ordered subset.

Fatalize
источник
0

Пакет, 234 232 байта

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

Работает рекурсивно, пытаясь вставить несовпадающие символы на обоих концах, поэтому очень медленно (я не пробовал последний тестовый пример). Пределы рекурсии означают, что в любом случае это работает только для ограниченной длины строки, так что 99это несколько произвольно. Я должен использовать callпараметры в качестве локальных переменных, так как я не смог заставить setlocalменя работать, что означает, что %1параметр :lподпрограммы является выражением, которое оценивает количество выполненных вставок.

Нил
источник