회문을 만들기위한 최소 삽입


15

오늘 당신은 또 다른 회문 도전을 할 것입니다!

따라서 오늘의 임무는 문자열을 가져와 회문으로 바꾸는 데 필요한 최소 글자 수를 결정하는 것입니다.

예를 들어 string을 가져옵니다 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
와우, 다시, 나는 이틀 전에이 정확한 도전 아이디어를 가지고 있었지만 점수 시스템은 코드 길이 + 코드 자체가 실행될 때의 출력이었습니다. (즉, 코드는 ppcg4 + 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 바이트 : -lQll.-Q.


3

파이썬, 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 ( "fishes", 0, 5)`와 같이로 .

설명이없는 골퍼 (정렬) :

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 Fixed .---
Oliver Ni

@ edc65 나는 etited.
Oliver Ni


2

Brachylog , 9 바이트

⊆P↔P;?lᵐ-

온라인으로 사용해보십시오!

삽입 맹목 화는 그 언어에서 매우 직관적이기 때문에이 과제는 Brachylog v2 답변이 실제로 필요했습니다.

설명

⊆P↔P삽입에 의한 palindromization은 실제로 무엇입니까 ( 이 예제 참조 )

⊆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 바이트

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

올리버 의 대답 의 뻔뻔한 항구는 더 짧은 해결책을 생각할 수 없었습니다.

gf문자열의 첫 번째 문자와 마지막 문자를 가리키는 포인터로 호출 합니다 (마지막 문자는 문자열이 아닌 문자열의 일부 임 '\0'). 더 비효율적입니다.fmin경우에 대해 두 번 호출 입니다.

언 골프 드 :

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
데이터로 추가 입력을받는 것은 기본적으로 합법적이지 않습니다
edc65

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.


0

배치, 234232 바이트

@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서브 루틴에 대한 매개 변수 는 지금까지 삽입 횟수로 평가되는 표현식입니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.