Bajar de categoría a Palindrome

47

Dada una cadena s, devuelve la subcadena contigua más pequeña que puedes eliminar para crear un palíndromo.


Ejemplos:

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

Sugerencias de casos de prueba de los usuarios (si encuentra un caso límite no listado, publique un comentario):

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

Reglas

  • Solo aparecerán caracteres ASCII imprimibles en la entrada (sin líneas nuevas, que sea simple).
  • En realidad, no una regla, pero nota <>, /\, (), []y {}no son palíndromos.

Este es el , el menor recuento de bytes gana.


+100 recompensa ha sido reclamada por Adnan

Urna de pulpo mágico
fuente
3
Caso Tesf:aabaab
Zgarb
14
Creo que ayudará a mantener las preguntas accesibles para más visitantes si se evita una jerga grupal como "CMC" (al buscarlo, parece significar "mini desafío de chat", lo que imagino significa un pequeño desafío publicado en la sala de chat asociado con este sitio).
ShreevatsaR
¿No es [[]]un palíndromo?
Carl
44
@Carl Puede parecer uno, pero cuando inviertes los caracteres, obtienes ]][[. Considera que aabbes lo mismo, solo personajes diferentes.
Conor O'Brien el
1
" (se otorgará 7/12) " ¿eh?
Erik the Outgolfer

Respuestas:

8

Jalea , 16 bytes

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

Pruébalo en línea!

Cómo funciona

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.
Dennis
fuente
10

J , 24 bytes

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

Pruébalo en línea!

Explicación

(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
millas
fuente
¿Quizás quiera elegir (;&quote f)&>como verbo de arnés de prueba?
Conor O'Brien el
7

Wolfram Language (Mathematica) , 53 51 bytes

El recuento de bytes supone la codificación CP-1252.

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

Pruébalo en línea!

Define un operador unario ±(o una función PlusMinus). La entrada y la salida son listas de caracteres. El conjunto de pruebas realiza la conversión desde y hacia cadenas reales para mayor comodidad.

Martin Ender
fuente
¿ ReverseEntonces, comparar ese reverso con el original es más corto que PalindromeQ? No conozco Mathematica, así que no tengo idea.
Urna mágica del pulpo
Buena respuesta, pero ¿no debería uno tener en cuenta la división de las cadenas y unirlas nuevamente en su recuento de caracteres? Characters@#/.{a___,Shortest@b___,c___}/;PalindromeQ[a<>c]:>b~~""&
Kelly Lowder
@MagicOctopusUrn Reverse[x={a,c}]==xes dos bytes más largo. No sé si hay alguna alternativa más corta.
Martin Ender
@KellyLowder Las listas de caracteres son representaciones válidas de cadenas en PPCG. Es un poco incómodo en Mathematica, donde normalmente no usarías esa representación, pero sigue siendo válida. Voy a desenterrar una meta publicación.
Martin Ender
1
@KellyLowder Creo que esta es la política aceptada . La razón principal por la que es incómodo en Mathematica es que Mathematica no tiene un tipo de carácter real, por lo que los caracteres terminan en cadenas simples.
Martin Ender
5

05AB1E , 18 bytes

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

Utiliza la codificación 05AB1E . Pruébalo en línea!

Adnan
fuente
Uso interesante del filtro allí ... Estábamos tratando de hacer un tipo de acuerdo "a sin b", pero si hubiera dos instancias de la subcadena, obtendríamos falsos negativos. Se siente como si estuviéramos complicando demasiado ahora que veo esto jajaja. Noice, te daré una recompensa de 100 en 2 días.
Urna mágica del pulpo
ǝfue en serio genio sin embargo.
Urna mágica del pulpo
3

Python 2 , 116 bytes

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)

Pruébalo en línea!

¡Ahorré un par de bytes con la ayuda de Halvard Hummel !

Sr. Xcoder
fuente
117 bytes
Halvard Hummel el
@HalvardHummel Gracias, estaba planeando cambiar eso también, pero no tuve conexión a Internet en las últimas 2 horas.
Sr. Xcoder
2

Japt , 26 22 bytes

¬£¬ËUjEY ꬩUtEY
c æ+0

¡Pruébelo en línea! Tratando de descubrir cómo mapear falsealgo falso y cualquier cadena a algo verdadero en un byte. Actualmente estoy usando +0...

ETHproducciones
fuente
2

Bash , 108 bytes

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
}
}

Toma entrada como argumento de línea de comando.

Pruébalo en línea! con comillas impresas alrededor de la salida para ver los espacios iniciales / finales.

Justin Mariner
fuente
2

Prólogo , 271 bytes

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

En algún momento me di cuenta de que esto sería enorme para los estándares de código de golf, así que mantuve algunos espacios en blanco adicionales para preservar el parecido con la versión no ofuscada. Pero sigo pensando que podría ser interesante ya que es un enfoque diferente del problema.

La versión no ofuscada:

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

C ++, 254 248 246 bytes

-6 bytes gracias a Zacharý -2 bytes gracias a 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"";}

Entonces...

  • Lo usé Tcomo una definición de macro porque lo hago R""como otro efecto en el literal de cadena (es un prefijo utilizado para definir literales de cadena sin procesar, vea cppreference para obtener más información) que no está allí cuando lo hagoT""
  • Las definiciones de preprocesador no pueden estar en la misma línea y deben tener al menos un espacio entre el nombre y el contenido en la definición
  • 2 funciones: p(std::string)para probar si la cadena es un palíndromo. Si es así, devuelve el 1que emite true, de lo contrario, regresa el 0que emitefalse
  • El algoritmo recorre toda la cadena y prueba si es un palíndromo al borrar cada vez 1 elemento, luego prueba borrar 2 elementos (recorre eso hasta el tamaño máximo de la cadena), desde el primer índice hasta the last index - number of erased char. Si encuentra que borrar alguna parte es un palíndromo, entonces regresa. Por ejemplo, cuando se pasa la cadena "aabcdbaa"como parámetro, tanto cy dson respuesta válida, pero el código volverá ca causa de borrarlos y probar si es un palíndromo viene antes de probar si el borrado dy probar si es palíndromo
  • Aquí está el código para probar:

    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';
        }
    }
HatsuPointerKun
fuente
¿Funcionaría esto para la última línea? 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ý
¿Se /2puede omitir? Iterar en toda la longitud simplemente repetirá las pruebas que hemos realizado, que deberían ser inofensivas. Es posible que desee ampliar lo que quiere decir con el "otro efecto" de R""(es decir, se analiza como un literal de cadena sin formato).
Toby Speight
Modifiqué esto y agregué el resultado como respuesta propia .
Toby Speight
1

PHP 104 + 1 bytes

while(~($s=$argn)[$e+$i++]?:++$e|$i=0)strrev($t=substr_replace($s,"",$i,$e))==$t&&die(substr($s,$i,$e));

Ejecutar como tubería -nRo probarlo en línea .

Titus
fuente
1

Haskell , 109105 bytes

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

Pruébalo en línea!

EDITAR: ¡Gracias @ H.PWiz por despegar 4 bytes! ¡Necesito mejorar con esas mónadas!

usuario1472751
fuente
1

JavaScript, 90 bytes

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

Pruébalo en línea!


fuente
1

Perl 5, 72 +1 (-p) bytes

$\=$_;/.*(?{$,=$`.$';$\=$&if length$&<length$\&&$,eq reverse$,})(?!)/g}{

Pruébalo en línea

Nahuel Fouilleul
fuente
1

JavaScript (ES6), 91 78 bytes

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

La entrada y la salida son listas de caracteres.

Recursivamente elimina una porción cada vez más grande de la entrada hasta que se encuentra un palíndromo.

Retazo:

Rick Hitchcock
fuente
1

TSQL (2016) 349B

No es la solución más compacta pero sencilla:

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
Jan Drozen
fuente
Se puede usar @como variable para unos pocos bytes. En el CTE puede usarlo where''=value)para otro y no necesita devolver Cel resultado.
MickyT
1

Casco , 18 bytes

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

Pruébalo en línea!

Explicación

◄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"
Zgarb
fuente
1

Haskell , 98 94 81 80 bytes

""#0
(h#n)t|(==)=<<reverse$h++drop n t=take n t|x:r<-t=(h++[x])#n$r|m<-n+1=t#m$h

Pruébalo en línea! Ejemplo de uso: ""#0 $ "aabaab"rendimientos "b".

Editar: -1 byte gracias a Ørjan Johansen.

Laikoni
fuente
1
Puede reemplazar el último ""por t.
Ørjan Johansen
1

C ++, 189 186 176 167 bytes

Comencé con la respuesta de HatsuPointerKun , cambiando la prueba para simplemente comparar la igualdad con la cadena invertida; luego cambié la forma en que enumeramos las cadenas de candidatos. Después de esto, las macros solo se usaron una o dos veces cada una, y fue más corto alinearlas.

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

Explicación

Código legible equivalente:

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
        }
    }
}

La enumeración de candidatos comienza inicializando una cadena con los primeros wcaracteres omitidos, y luego copiando los caracteres sucesivos del original para mover la brecha. Por ejemplo, con la cadena foobary w== 2:

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

El primer paso (con w== 0) es un no-op, por lo que la cadena completa se considerará una y otra vez. Eso está bien: ¡el golf supera la eficiencia! La última iteración de este bucle accederá al índice de una pasada; Parece que me salgo con la suya con GCC, pero estrictamente, ese es un comportamiento indefinido.

Programa de prueba

Un levantamiento directo de la respuesta de 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';
        }
    }
}
Toby Speight
fuente
0

REXX, 132 bytes

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
idrougge
fuente
0

Ruby , 86 84 bytes

->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]}

Pruébalo en línea!

  • Guardado 2 bytes gracias a Cyoce
Restablecer a Monica iamnotmaynard
fuente
No necesitas los paréntesis z=s.size-l+1.
Cyoce
@Cyoce Gracias. Me cuesta recordar toda la precedencia del operador.
Restablece a Monica iamnotmaynard el
0

C (gcc) , 307 bytes

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

Pruébalo en línea!

R. Kap
fuente