Перехід до Паліндрому


47

Враховуючи рядок s, поверніть найменшу суміжну підрядку, яку ви можете видалити, щоб створити паліндром.


Приклади:

800233008   -> 2
racecarFOOL -> FOOL
abcdedcba   -> (empty string)
ngryL Myrgn -> "L " (or " M")
123456789   -> 12345678 (or 23456789)
aabcdbaa    -> c (or d)
[[]]        -> [[ (or ]])
a           -> (empty string)

Пропозиції для тестових випадків від користувачів (якщо кращий регістр не вказаний, будь ласка, опублікуйте коментар):

aabaab      -> b    | Suggested by Zgarb, some returned "aa".

Правила

  • Лише ASCII символи для друку з'являться на вводі (жодних нових рядків, нехай це буде просто).
  • Не зовсім правило, але зауважте <>, /\, (), []і {}НЕ палиндромов.

Це , найменший виграш у кількості байтів.


+100 щедрості вимагає Аднана


3
Справа Тесфа:aabaab
Згарб

14
Я думаю, що це допоможе зберегти питання доступними для більшої кількості відвідувачів, якщо уникнути розгрупування жаргону на зразок "CMC" (переглянувши його, схоже, що це "чат міні-виклик", що, на мою думку, означає невеликий виклик, розміщений у чаті, пов’язаний із цей сайт).
ShreevatsaR

Чи не [[]]паліндром?
Карл

4
@Carl Це може виглядати так, але коли ви перевертаєте символи, ви отримуєте ]][[. Вважайте, що aabbце одне і те ж, просто різні персонажі.
Conor O'Brien

1
" (буде присуджено 7/12) " так?
Ерік Аутгольфер

Відповіді:


8

Желе , 16 байт

Ḣ;Ṫµ=Ṛ
0,0jŒṖÇÞṪ

Спробуйте в Інтернеті!

Як це працює

0,0jŒṖÇÞṪ  Main link. Argument: s (string)

0,0j       Join [0, 0], separating by s. This prepends and appends a 0 to s.
    ŒṖ     Build all partitions of the resulting array.
      ÇÞ   Sort the partitions by the helper link.
           As a side effect, this will remove the first and last element of each
           partition. The 0's make sure that not removing any characters from s
           will still remove [0] from both sides.
        Ṫ  Tail; extract the last one.


Ḣ;Ṫµ=Ṛ     Helper link. Argument: A (array/partition)

Ḣ          Head; yield and remove the first chunk of A.
  Ṫ        Tail; yield and remove the last chunk of A.
 ;         Concatenate head and tail.
   µ=Ṛ     Compare the result, character by character, with its reverse.
           A palindrome of length l will yield an array of l 1's, while a
           non-palindrome of length l will yield an array with at least one 0 among
           the first l/2 Booleans. The lexicographically largest result is the one
           with the longest prefix of 1's, which corresponds to the longest
           palindrome among the outfixes.

10

J , 24 байти

(0{::(-:|.)\.#&,<\)~i.@#

Спробуйте в Інтернеті!

Пояснення

(0{::(-:|.)\.#&,<\)~i.@#  Input: array of chars S
                       #  Length of S
                    i.@   Range, [0, 1, ..., len(S)-1]
(                 )~      Dyadic verb on range and S
           \.               For each outfix of S of size x in range
        |.                    Reverse
      -:                      Matches input (is palindrome)
                <\          Box each infix of S of size x in range
             #&,            Flatten each and copy the ones that match
 0{::                       Fetch the result and index 0 and return

Можливо, ви можете вибрати (;&quote f)&>як дієслово тестової запряжки?
Conor O'Brien

7

Мова Вольфрама (Mathematica) , 53 51 байт

Кількість байтів передбачає кодування CP-1252.

±{a___,Shortest@b___,c___}/;PalindromeQ[a<>c]:={b}

Спробуйте в Інтернеті!

Визначає одинарний оператор ±(або функцію PlusMinus). Введення та вихід - це списки символів. Тестовий набір для зручності робить перетворення з та у фактичні рядки.


Чи Reverseпорівнюється тоді цей зворотний з оригіналом коротший ніж PalindromeQ? Я не знаю Mathematica, так що ідеї немає.
Чарівний восьминіг Урна

Хороша відповідь, але чи не слід вважати розбиття рядків та об'єднання їх назад у вашому підрахунку символів? Characters@#/.{a___,Shortest@b___,c___}/;PalindromeQ[a<>c]:>b~~""&
Келлі Лоудер

@MagicOctopusUrn Reverse[x={a,c}]==xна два байти довше. Я не знаю, чи існує якась коротша альтернатива.
Мартін Ендер

@KellyLowder Списки символів - це дійсні зображення рядків на PPCG. Це трохи незручно в Mathematica, де ви зазвичай не використовуєте це представлення, але воно все ще діє. Я викопаю мета-пост.
Мартін Ендер

1
@KellyLowder Я думаю, що це прийнята політика . Основна причина, чому це незручно в Mathematica, полягає в тому, що Mathematica не має фактичного типу символів, тому символи в кінцевому підсумку є однорядними рядками.
Мартін Ендер


5

05AB1E , 18 байт

ā<Œ¯¸«ʒRõsǝÂQ}éнèJ

Використовує кодування 05AB1E . Спробуйте в Інтернеті!


Цікаве використання фільтра там ... Ми намагалися зробити угоду типу "a без b", але якби було два екземпляри підрядка, ми отримали помилкові негативи. Відчуває, що ми надто ускладнювали це зараз, коли я бачу цю хаха. Зауважте, я дам вам 100 баунтів за 2 дні.
Magic Octopus Urn

ǝбув серйозно геніальним.
Чарівний восьминога Урна


3

Python 2 , 116 байт

def f(i):R=range(len(i)+1);print min([i[y:k+1]for y in R for k in R if(i[:y]+i[k+1:])[::-1]==i[:y]+i[k+1:]],key=len)

Спробуйте в Інтернеті!

Зберегли пару байтів за допомогою Halvard Hummel !



@HalvardHummel Спасибі, я теж планував це змінити, але не мав підключення до Інтернету протягом останніх 2 годин.
Містер Xcoder

2

Japt , 26 22 байт

¬£¬ËUjEY ꬩUtEY
c æ+0

Перевірте це в Інтернеті! Намагаюся зрозуміти, як falseв одному байті відобразити , як відобразити щось фальшиве та будь-який рядок на щось трибунове. Наразі я використовую +0...



2

Пролог , 271 байт

p([_]).
p([X,X]).
p([X|Y]):-append([P,[X]],Y),p(P).

s(P,M,S,R,N):-p(P),append([M,S],N).
s(P,M,S,S,N):-p(S),append([P,M],N).
s(P,M,S,P,M):-append([P,S],X),p(X).

d(Y,P,N):-
    findall([A,B,C],(append([R,M,X],Y),s(R,M,X,B,C),length(B,A)),S),
    sort(1,@>,S,[[_,P,N]|_]).

У якийсь момент я зрозумів, що це буде величезним за стандартами коду-гольфу, тому я зберег кілька зайвих порожніх просторів, щоб зберегти схожість з непритомною версією. Але я все ж думаю, що це може бути цікавим, оскільки це інший підхід до проблеми.

Неприхована версія:

palindrome([_]).
palindrome([X, X]).
palindrome([X | Xs]) :-
    append([Prefix, [X]], Xs),
    palindrome(Prefix).

palindrome_split(Prefix, Mid, Suffix, Prefix, N) :-
    palindrome(Prefix),
    append([Mid, Suffix], N).
palindrome_split(Prefix, Mid, Suffix, Suffix, N) :-
    palindrome(Suffix),
    append([Prefix, Mid], N).
palindrome_split(Prefix, Mid, Suffix, P, Mid) :-
    append([Prefix, Suffix], P),
    palindrome(P).

palindrome_downgrade(NP, P, N):-
    findall(
        [La, Pa, Na],
        (append([Prefix, Mid, Suffix], NP),
         palindrome_split(Prefix, Mid, Suffix, Pa, Na),
         length(Pa, La)),
        Palindromes),
    sort(1, @>, Palindromes, [[_, P, N] | _]).

2

C ++, 254 248 246 байт

-6 байт завдяки Zacharý -2 байти завдяки Toby Speight

#include<string>
#define S size()
#define T return
using s=std::string;int p(s t){for(int i=0;i<t.S;++i)if(t[i]!=t[t.S-i-1])T 0;T 1;}s d(s e){if(!p(e))for(int i,w=1;w<e.S;++w)for(i=0;i<=e.S-w;++i){s t=e;t.erase(i,w);if(p(t))T e.substr(i,w);}T"";}

Тому...

  • Я використовувався Tяк визначення макросу, тому що це робиться R""як інший ефект на рядковий літерал (це префікс, який використовується для визначення необроблених рядкових літералів, див. Cppreference для отримання додаткової інформації), якого немає, коли я це роблюT""
  • Визначення препроцесора не можуть бути в одному рядку і повинні мати принаймні один пробіл між ім'ям та вмістом у визначенні
  • 2 функції: p(std::string)перевірити, чи є рядок паліндром. Якщо це так, він повертає те, 1що кидає true, інше - повертає 0, яке кидаєfalse
  • Алгоритм здійснює циклічне тестування на весь тест рядка, якщо це паліндром при стиранні кожного разу по 1 елементу, а потім випробування стирання 2 елементів (циклів над цим на максимальний розмір рядка) від першого індексу до the last index - number of erased char. Якщо він виявить, що стирання якоїсь частини є паліндром, значить, вона повертається. Наприклад, при передачі рядка "aabcdbaa"як параметра обидва cі dє дійсною відповіддю, але цей код повернеться, cтому що стирання його та тестування, якщо це паліндром, приходить до тестування, якщо стирання dта тестування, якщо це паліндром
  • Ось код для тестування:

    std::initializer_list<std::pair<std::string, std::string>> test{
        {"800233008","2"},
        { "racecarFOOL","FOOL" },
        { "abcdedcba","" },
        { "ngryL Myrgn","L " },
        { "123456789","12345678" },
        { "aabcdbaa","c" },
        { "[[]]","[[" },
        { "a","" },
        { "aabaab","b" }
    };
    
    for (const auto& a : test) {
        if (a.second != d(a.first)) {
            std::cout << "Error on : " << a.first << " - Answer : " << a.second  << " - Current : " << d(a.first) << '\n';
        }
    }

Це працювало б для останнього рядка? using s=std::string;int p(s t){for(int i=0;i<t.S/2;++i)if(t[i]!=t[t.S-i-1])T 0;T 1;}s d(s e){if(!p(e))for(int i,w=1;w<e.S;++w)for(i=0;i<=e.S-w;++i){s t=e;t.erase(i,w);if(p(t))T e.substr(i,w);}T"";}
Zacharý

Чи /2можна пропустити? Ітерація по всій довжині просто повторить тести, які ми зробили, які повинні бути нешкідливими. Ви можете розширити те, що ви маєте на увазі під "іншим ефектом" R""(тобто це проаналізовано як необроблений рядковий літерал).
Toby Speight

Я це змінив і додав результат як власну відповідь .
Toby Speight




1

JavaScript, 90 байт

a=>a.map((_,p)=>a.map((_,q)=>k||(t=(b=[...a]).splice(q,p),k=''+b==b.reverse()&&t)),k=0)&&k

Спробуйте в Інтернеті!



1

JavaScript (ES6), 91 78 байт

(s,i=0,j=0,S=[...s],b=S.splice(i,j))=>S+''==S.reverse()?b:f(s,s[++i]?i:!++j,j)

Введення та вихід - це списки символів.

Рекурсивно видаляє більший і більший зріз із входу, поки не буде знайдено паліндром.

Фрагмент:


1

TSQL (2016) 349B

Не най компактніше, але просте рішення:

DECLARE @i VARCHAR(255)='racecarFOOL'
;WITH DAT(v,i,l)AS(SELECT value,(ROW_NUMBER()OVER(ORDER BY value))-1,LEN(@i)FROM STRING_SPLIT(REPLICATE(@i+';',LEN(@i)+1),';')WHERE value<>'')
SELECT TOP 1C,S
FROM(SELECT LEFT(D.v, D.i)+SUBSTRING(D.v,D.i+E.i+1,D.l)C,SUBSTRING(D.v,D.i+1,E.i)S
FROM DAT D CROSS APPLY DAT E)C
WHERE C=REVERSE(C)
ORDER BY LEN(C)DESC

Ви можете використовувати @як змінну на кілька байт. У CTE ви можете скористатися where''=value)ще одним, і не потрібно повертати Cрезультат.
MickyT

1

Лушпиння , 18 байт

◄LfmS=↔†!⁰ṠM-Qŀ⁰Q⁰

Спробуйте в Інтернеті!

Пояснення

◄LfmS=↔†!⁰ṠM-Qŀ⁰Q⁰  Input is a string, say s="aab"
              ŀ⁰    Indices of s: x=[1,2,3]
             Q      Slices: [[],[1],[1,2],[2],[1,2,3],[2,3],[3]]
          ṠM-       Remove each from x: [[1,2,3],[2,3],[3],[1,3],[],[1],[1,2]]
       †!⁰          Index into s: ["aab","ab","b","ab","","a","aa"]
   mS=↔             Check which are palindromes: [0,0,1,0,1,1,1]
  f             Q⁰  Filter the slices of s by this list: ["aa","aab","ab","b"]
◄L                  Minimum on length: "b"


1

C ++, 189 186 176 167 байт

Я почав з відповіді HatsuPointerKun , змінивши тест, щоб просто порівняти рівність із зворотним рядком; потім я змінив, як ми перераховуємо рядки кандидатів. Після цього макроси використовувались лише один або два рази кожен, і їх було коротше вбудовувати.

#include<string>
using s=std::string;s d(s e){for(int i,w=0;;++w){s t=e.substr(w);for(i=-1;++i<=t.size();t[i]=e[i])if(t==s{t.rbegin(),t.rend()})return e.substr(i,w);}}

Пояснення

Еквівалентний читабельний код:

std::string downgrade(std::string e)
{
    for (int w=0; ; ++w) {
        std::string t = e.substr(w);
        for (int i=0;  i<=t.size();  ++i) {
            if (t == std::string{t.rbegin(),t.rend()})
                // We made a palindrome by removing w chars beginning at i
                return e.substr(i,w);
            t[i] = e[i];  // next candidate
        }
    }
}

Перерахування кандидатів починається з ініціалізації рядка з wпропущеними першими символами, а потім копіювання послідовних символів з оригіналу для переміщення пробілу. Наприклад, з рядком foobarі w== 2:

foobar
  ↓↓↓↓
  obar
foobar
↓
fbar
foobar
 ↓
foar
foobar
  ↓
foor
foobar
   ↓
foob

Перший пропуск (з w== 0) - неоперативний, тому повна рядок буде розглядатися знову і знову. Це нормально - ефективність козирних гольфів! Остання ітерація цього циклу матиме доступ до індексу минулого кінця; Мені здається, це не вдається розібратися з GCC, але суворо, це не визначена поведінка.

Тестова програма

Прямий вихід з відповіді HatsuPointerKun :

static const std::initializer_list<std::pair<std::string, std::string>> test{
    { "800233008", "2" },
    { "racecarFOOL", "FOOL" },
    { "abcdedcba", "" },
    { "ngryL Myrgn", "L " },
    { "123456789", "12345678" },
    { "aabcdbaa", "c" },
    { "[[]]", "[[" },
    { "a","" },
    { "aabaab", "b" }
};

#include <iostream>
int main()
{
    for (const auto& a : test) {
        if (a.second != d(a.first)) {
            std::cout << "Error on: " << a.first
                      << " - Expected: " << a.second
                      << " - Actual: " << d(a.first) << '\n';
        }
    }
}

0

REXX, 132 байти

a=arg(1)
l=length(a)
do i=1 to l
  do j=0 to l-i+1
    b=delstr(a,i,j)
    if b=reverse(b) & m>j then do
      m=j
      s=substr(a,i,j)
      end
    end
  end
say s


0

C (gcc) , 307 байт

#define T malloc(K)
P(S,i,y,z,k,u,L,K,V)char*S;{char*M,*R,*E;K=strlen(S);M=T;R=T;E=T;for(i=0;i<K;++i){for(y=0;y<=K-i;++y){strcpy(M,S);for(z=y;z<y+i;E[z-y]=M[z],++z);for(k=y;k+i<=K;M[k]=M[k+i],++k);V=strlen(M);strcpy(R,M);for(u=0;u<V/2;L=R[u],R[u]=R[V-u-1],R[V-u-1]=L,++u);if(!strcmp(M,R))puts(E),exit(0);}}}

Спробуйте в Інтернеті!

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.