Chèn tối thiểu để làm cho palindrom


15

Hôm nay bạn sẽ thực hiện một thử thách palindrom khác!

Vì vậy, nhiệm vụ của bạn hôm nay là lấy một chuỗi và xác định số lượng chữ cái tối thiểu cần thiết để chèn để biến nó thành một bảng màu.

Ví dụ: hãy lấy chuỗi fishes.

Trong trường hợp này, cách tốt nhất là thêm h if, vì vậy kết quả sẽ là 3.

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

Bây giờ hãy thử với codegolf. Vì có một sự lặp lại o, chúng ta chỉ có thể làm:

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

để có kết quả là 5.

Các trường hợp thử nghiệm

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

1
Liên quan , với chèn vào chỉ xảy ra ở bên phải.
xnor

2
Wow, một lần nữa, tôi đã có ý tưởng thử thách chính xác này hai ngày trước ... nhưng hệ thống tính điểm sẽ là độ dài mã của bạn + đầu ra khi mã của nó chạy qua chính nó. (tức là mã là ppcg, điểm số là 4 + 2 = 6)
ETHproductions

5
Đây là một thử thách thú vị, nhưng tôi thích nếu các thử thách cùng chủ đề được đặt ra nhiều hơn. Có rất nhiều palindrom trong vài ngày qua.
xnor

1
Thật khó để chứng minh rằng một chương trình nhất định thực sự tìm thấy số lượng chữ cái tối thiểu
edc65

Câu trả lời:


3

Bình thường, 10 byte

bộ kiểm tra.

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

Có một vài đặc điểm tương đương của giá trị chúng tôi theo sau:

  • Số lần chèn ít nhất cần thiết để tạo một bảng màu
  • Việc xóa ít nhất cần thiết để tạo một bảng màu
  • Một nửa số thao tác xóa hoặc chèn cần thiết để chuyển đổi chuỗi thành ngược lại
  • Độ dài của đầu vào với chuỗi con palindromic dài nhất của nó đã bị xóa
  • Độ dài của đầu vào, loại bỏ chuỗi con chung dài nhất giữa nó và đảo ngược của nó. (Mã sử ​​dụng cái này.)

Ý tưởng phổ biến là "bộ xương" của các chữ cái trong đầu vào khớp với các chữ cái của đầu vào trong sản phẩm cuối cùng.

  codeg  o lf
   *  *  *
fl o  gedoc 

flcodegedoclf

Bộ xương này luôn luôn là một bảng màu, với các chữ cái khớp với các đối tác đảo ngược của chúng. Mỗi chữ cái không có khung là không thể so sánh được và phải có đối tác của nó được chèn vào.

Một thay thế có cùng độ dài thay vì sử dụng điều kiện thứ tư, độ dài của đầu vào trừ đi độ dài của chuỗi sau palindromic dài nhất của nó

l.-Qef_ITy

Liên kết đến bộ kiểm tra.

Phần khác nhau là

f_ITy

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

Đối với cả hai, thay vì loại bỏ chuỗi con palindromic khỏi đầu vào và lấy độ dài, thay vào đó chúng ta có thể trừ chiều dài của nó khỏi chiều dài của đầu vào. Hoặc là một chi phí 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)

Rất kém hiệu quả.

Hãy thử trực tuyến! Bạn phải đợi một phút để trường hợp cuối cùng kết thúc.

Gọi với e(<string>, 0, <length of string - 1>), như e ("cá", 0, 5) `.

Ungolfed (loại) với lời giải thích:

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
Theo mặc định, việc nhập thêm dữ liệu (độ dài danh sách) không hợp pháp. Không phải là đầu vào của 0, nhưng bạn có thể sửa nó bằng một đối số mặc định l=0.
xnor

@xnor Đã sửa .---
Oliver Ni

@ edc65 Tôi đã xác nhận.
Oliver Ni

2

05AB1E , 11 byte

Sử dụng mã hóa CP-1252 .

Âæsæäg¹g-Ä

Hãy thử trực tuyến! hoặc như một bộ thử nghiệm

Giải trình

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

Hãy thử trực tuyến!

Thử thách này thực sự cần một câu trả lời Brachylog v2, vì việc chèn vào bảng chữ cái rất trực quan trong ngôn ngữ đó.

Giải trình

⊆P↔Pthực sự là những gì không palindromization bằng cách chèn (xem ví dụ này )

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

Cổng không biết xấu hổ về câu trả lời của Oliver , không thể nghĩ ra giải pháp nào ngắn hơn.

ggọi fbằng con trỏ đến char đầu tiên và char cuối cùng của chuỗi (char cuối cùng là một phần của chuỗi, không phải là chuỗi '\0'). Thậm chí còn kém hiệu quả hơn vì fđược gọi hai lần cho minvụ án.

Ung dung:

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
 }

Sử dụng:

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

2
Nhận một đầu vào bổ sung với dữ liệu không hợp pháp theo mặc định
edc65

1

Brachylog v1 , 13 byte

,IrIs?:I:lar-

Hãy thử trực tuyến!

Bạn có thể kiểm tra các palindromes nó tìm thấy với mã này .

Giải trình

Tôi gần như ngạc nhiên khi điều này thậm chí hoạt động, thấy nó đơn giản đến mức nực cười.

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

Điều này được đảm bảo để tìm ra bảng màu nhỏ nhất vì IrIsẽ tạo ra các chuỗi có độ dài tăng dần khi quay lại, bắt đầu từ chuỗi trống.

Điều này không đủ hiệu quả để tính toán trường hợp thử nghiệm cuối cùng trên TIO, vì việc sử dụng s - Ordered subset.


0

Mẻ, 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%

Hoạt động bằng cách đệ quy cố gắng chèn các ký tự không khớp ở cả hai đầu, vì vậy rất chậm (tôi đã không thử trường hợp thử nghiệm cuối cùng). Giới hạn đệ quy có nghĩa là điều này chỉ hoạt động với độ dài chuỗi giới hạn, do đó, điều 99này có phần tùy ý. Tôi phải sử dụng callcác tham số làm biến cục bộ vì tôi không thể setlocallàm việc cho tôi, điều đó có nghĩa là %1tham số đó cho :lchương trình con là một biểu thức đánh giá số lần chèn được thực hiện cho đến nay.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.