Понижение до палиндрома


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это одно и то же, просто разные персонажи.
Конор О'Брайен

1
" (будет награжден 7/12) " да?
Эрик Outgolfer

Ответы:


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)&>в качестве тестового глагола?
Конор О'Брайен

7

Wolfram Language (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 . Попробуйте онлайн!


Интересное использование там фильтра ... Мы пытались заключить сделку типа «без б», но если бы было два экземпляра подстроки, мы получили бы ложные отрицания. Такое чувство, что мы слишком усложнили это сейчас, когда я вижу это, лол. Обратите внимание, я дам вам 100 наград за 2 дня.
Волшебная Урна Осьминога

ǝбыл серьезно гением, хотя
Волшебная Осьминог Урна


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)

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

Спасли пару байтов с помощью Халварда Хаммеля !



@HalvardHummel Спасибо, я тоже планировал это изменить, но последние 2 часа у меня не было подключения к интернету.
г-н Xcoder


2

Баш , 108 байт

for((j=0;;j++)){
for((i=0;i<${#1};i++)){
r=${1:0:i}${1:j+i}
[[ $r = `rev<<<$r` ]]&&echo "${1:i:j}"&&exit
}
}

Принимает ввод в качестве аргумента командной строки.

Попробуйте онлайн! с кавычками, напечатанными вокруг выхода для просмотра начальных / конечных пробелов.


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]|_]).

В какой-то момент я понял, что это будет огромным по стандартам code-golf, поэтому я оставил несколько лишних пробелов, чтобы сохранить сходство с неясной версией. Но я все еще думаю, что это может быть интересно, так как это другой подход к проблеме.

Не запутанная версия:

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 байтов благодаря Захарию -2 байта благодаря Тоби Спейту

#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"";}
Захари

Может /2быть опущен? Повторение по всей длине просто повторит тесты, которые мы сделали, что должно быть безвредным. Возможно, вы захотите расширить то, что вы подразумеваете под «другим эффектом» R""(т. Е. Он анализируется как необработанный строковый литерал).
Тоби Спейт

Я изменил это и добавил результат в качестве собственного ответа .
Тоби Спейт



1

Haskell , 109 105 байт

snd.minimum.([]#)
p#s@(a:b)=[(i,take i s)|i<-[0..length s],(==)<*>reverse$p++drop i s]++(p++[a])#b
p#_=[]

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

РЕДАКТИРОВАТЬ: Спасибо @ H.PWiz за удаление 4 байта! Мне нужно поправиться с этими монадами!


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, но строго говоря, это неопределенное поведение.

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

Прямой ответ от ответа ХацуПоинтерКуна :

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

Рубин , 86 84 байта

->s{l=i=0
(l+=(i+=1)/z=s.size-l+1
i%=z)while(w=s[0,i]+s[i+l..-1])!=w.reverse
s[i,l]}

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

  • Сохранено 2 байта благодаря Cyoce

Вам не нужны круглые скобки z=s.size-l+1.
Cyoce

@Cyoce Спасибо. Мне трудно вспомнить все операторские приоритеты.
Восстановить Монику iamnotmaynard

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.