¿Dónde debo poner mi espejo?

30

Este es un espejo: |. ¡Acabo de descubrir que puedes pegar un espejo en el medio de una cuerda si la cuerda se puede reflejar en sí misma! Por ejemplo, la cadena abccba. Si lo corta por la mitad, las dos mitades son imágenes especulares entre sí:

abc  <-->  cba

Entonces, podemos pegar un espejo en el medio de la cadena, y nuestra nueva cadena es abc|cba. A veces, solo parte de la cadena se puede reflejar en sí misma. Por ejemplo, la cadena "espejo". Las dos r se reflejan, pero el resto de la cadena no. Está bien, simplemente eliminaremos las partes de la cadena que no se reflejan entre sí, y obtenemos la siguiente cadena:

r|r

Algunas cadenas pueden reflejarse en múltiples lugares. Por ejemplo, "Hola mundo, xyzzyx". Me gusta tener un montón de texto reflejado en mi espejo, por lo que debes encontrar el mejor lugar para poner mi espejo. En este caso, debe generar la cadena reflejada más larga y, al igual que en nuestro último ejemplo, eliminar todo lo demás. Esta cadena se convierte en:

xyz|zyx

Algunas cadenas mirar como que se pueden reflejar, pero en realidad no pueden. Si una cadena no se puede reflejar en ningún lado, no debe generar nada.

El reto:

Dada una cadena que contiene solo ascii imprimible, encuentra el mejor lugar para poner mi espejo. En otras palabras,

Encuentre la subcadena palindrómica de longitud par más grande, luego envíela con un carácter de tubería '|' en el medio

La entrada tendrá 1-50 caracteres de longitud.

Puede suponer que la entrada no contendrá espejos |o nuevas líneas. Más allá de eso, todos los personajes imprimibles-ascii son juegos justos. Si la subcadena reflejada más larga está vinculada entre dos subcadenas, puede elegir cuál generar. Por ejemplo, para la cadena "abba ollo", debe generar "ab | ba" u "ol | lo", pero no importa cuál genere. Las cadenas distinguen entre mayúsculas y minúsculas, por ejemplo, "ABba" no debería generar "AB | ba", debería generar la cadena vacía.

Muestra IO:

"Hello World"     --> "l|l"
"Programming Puzzles and Code-Golf"     --> Either "m|m" or "z|z"
"abcba"           --> ""
"Hulluh"          --> "ul|lu"
"abcdefggfedcba"  --> "abcdefg|gfedcba"
"abcdefggfabc"    --> "fg|gf"
"AbbA"            --> "Ab|bA"
"This input is a lot like the last one, but with more characters that don't change the output. AbbA" --> "Ab|bA"

Como de costumbre, este es el código de golf, por lo que se aplican las lagunas estándar, ¡y gana la respuesta más corta en bytes!

DJMcMayhem
fuente
¿Hay un límite en la longitud de la entrada?
Mego
@Mego Mientras su algoritmo funcione teóricamente en cualquier entrada, no me importa cuánto tiempo tome / cuánta memoria tome.
DJMcMayhem
Le pregunté porque los motores Vange Regex solo son capaces de combinar palíndromos de longitud hasta un valor finito específico (en oposición a palíndromos arbitrariamente largos), y la posibilidad de una solución basada en expresiones regulares dependerá de si existe o no un valor superior. vinculado a la longitud de la entrada.
Mego
@Mego Ah, eso tiene sentido. Digamos que la entrada puede tener hasta 50 caracteres de longitud. ¿Como suena eso?
DJMcMayhem

Respuestas:

9

Pyth - 19 17 15 13 bytes

Gracias a @FryAmTheEggman por salvarme dos bytes.

ARRGH el caso especial de no respuesta. Resuelto eso!

e_I#jL\|cL2.:

Test Suite .

e                Last element in list, this works out to longest one
  _I             Invariance under reverse, this detect palindrome
   #             Filter
   jL            Map join
    \|           By "|"
    cL2          Map chop in two pieces
     .:Q)        Substrings. Implicit Q). ) makes it do all substrings.
Maltysen
fuente
2
Nooooo! Ninja'd a la respuesta pyth; _;
Downgoat
¿Explicación por favor? : 3
Downgoat
@Downgoat tomó todas las subcadenas y las cortó en dos, unió cada par con |, filtró por simetría, lo agregó a [k] y obtuvo el último elemento (que es el más largo)
busukxuan
@Downgoat hecho.
Maltysen
2
:Q)= Bignose
gcampbell
8

05AB1E , 19 17 14 bytes

Código:

Œévy2ä'|ý©ÂQi®

Explicación:

Œ                # Get all substrings of the input
 é               # Sort by length (shortest first)
  vy             # For each element...
    2ä           # Split into two pieces
      '|ý        # Join by "|"
         ©       # Copy this into the register
          Â      # Bifurcate, pushing a and reversed a
           Q     # Check if it's a palindrome
            i®   # If so, push that string again
                 # Implicit, the top element is outputted

Utiliza la codificación CP-1252 . Pruébalo en línea! .

Adnan
fuente
5

Python 2, 102 97 bytes

def f(s):h=len(s)/2;r=s[:h]+'|'+s[h:];return s and max(r*(r==r[::-1]),f(s[1:]),f(s[:-1]),key=len)

Más bien lento e ineficiente ... Verifique los casos de prueba más pequeños en Ideone .

Dennis
fuente
4

JavaScript, 100 99 bytes

s=>eval('for(O=i=0;s[i++];O=O[j+j]?O:o)for(o="|",j=0;(S=s[i-1-j])&&S==s[i+j++];o=S+o+S);O[1]?O:""')

o

s=>eval('for(O="",i=0;s[i++];O=O[j+j]||j<2?O:o)for(o="|",j=0;(S=s[i-1-j])&&S==s[i+j++];o=S+o+S);O')
jrich
fuente
Por curiosidad, ¿para qué sirve eval?
gcampbell
@gcampbell evalpara evitarreturn
edc65
¿No puedes usar el operador de coma para evitar el retorno?
MayorMonty
@SpeedyNinja no. forno es una expresión, por lo que normalmente requeriría llaves y unreturn
jrich
3

Lua, 133 bytes

s=...for i=#s,1,-1 do for j=1,#s-i do m=j+i/2-i%2/2t=s:sub(j,m).."|"..s:sub(m+1,i+j)if t==t.reverse(t)then print(t)return end end end

Verifique todos los casos de prueba en Ideone.com .

Monja permeable
fuente
1
Úselo t==t:reverse()para guardar un byte :)
Katenkyo
2

Retina , 66 bytes

El recuento de bytes asume la codificación ISO 8859-1.

M!&`(.)+(?<-1>\1)+(?(1)¶)
O$#`.+
$.&
A-2`
^(.)+?(?=(?<-1>.)+$)
$&|

Pruébalo en línea! (La primera línea permite probar varios casos de prueba separados por salto de línea a la vez).

Hmmm, mucho más de lo que me gustaría ...

Martin Ender
fuente
2

JavaScript (ES6), 91

s=>[...s].map((d,i)=>{for(a='|',j=0;d=s[i-j],d&&d==s[i-~j];r=r[j+++j]?r:a)a=d+a+d},r='')&&r

Menos golf

f=s=>
  [...s].map(
    (d,i) => {
    for(a='|', j=0; d=s[i-j], d&&d==s[i-~j]; r = r[j++ +j]? r : a)
      a = d+a+d
    }, r=''
  ) && r

Prueba

F=
s=>[...s].map((d,i)=>{for(a='|',j=0;d=s[i-j],d&&d==s[i-~j];r=r[j+++j]?r:a)a=d+a+d},r='')&&r

;[["Hello World", "l|l"]
,["Programming Puzzles and Code-Golf", "m|m"]
,["abcba", ""]
,["Hulluh", "ul|lu"]
,["abcdefggfedcba", "abcdefg|gfedcba"]
,["abcdefggfabc", "fg|gf"]
,["AbbA", "Ab|bA"]
,["This input is a lot like the last one, but with more characters that don't change the output. AbbA", "Ab|bA"]]
.forEach(t=>{
  var i=t[0],k=t[1],r=F(i)
  console.log(k==r?'OK ':'KO ',i+' -> '+r,k!=r?'(check '+k+')':'')
})  

edc65
fuente
2

Perl 5, 105 100 98 + 1 = 106 101 99 bytes

/(?=((.)(?1)?\2)(?{[push@_,$1})(?!))/;($_)=sort{length$b<=>length$a}@_;substr($_,length>>1,0)='|'if$_

Solo quería probar las expresiones regulares recursivas. Necesita la -popción. Editar: Guardado (tachado 4) 7 bytes gracias a @ msh210. (El byte faltante se debe a un ahorro que fue reemplazado por el último ahorro de @ msh210).

Neil
fuente
No he probado ninguno de estos, pero probablemente esto se puede abreviar de varias maneras, incluyendo: (1) @_=(@_,$1)puede ser push@_,$1. (2) Omita las líneas nuevas y la final ;. (3) Sospecho que hay una condición de clasificación más corto puede utilizar (si no otra cosa, al menos, a continuación, tal vez --- --- sustituto -para <=>)
msh210
@ msh210 Gracias por los dos primeros puntos, pero ya lo intenté -y no funcionó (probablemente necesite parens para tener prioridad, lo que vence el ahorro).
Neil
Probar y...c>>1o en y...c/2lugar de length>>1. (Sin probar)
msh210
@ msh210 Obviamente debería haber leído los consejos para jugar golf en Perl primero ...
Neil
Supongo que tu último par de padres también puede irse.
msh210
2

Python 2, 91 bytes

f=lambda s,p='':s and max((''<p<=s<p+'\x7f')*(p[::-1]+'|'+p),f(s[1:]),f(s[1:],s[0]+p),key=len)

Reemplace \x7fcon el carácter real DEL, que es ASCII 127 (crédito a Dennis).

Esto sigue una estrategia similar a la respuesta de Dennis de usar maxy ramificar recursivamente para encontrar el intervalo de palíndromo más largo. Pero, en cambio, encuentra la mitad izquierda, verificando que la mitad derecha reflejada correspondiente viene justo después con un inicio hecho a sí mismo .

La función adivina si el primer carácter está en la mitad izquierda reflejada. Si no, simplemente lo suelta y vuelve a aparecer en el resto. Si es así, se agrega a la pila pde caracteres invertidos. Si la cadena comienza con la pila, la cadena espejo se genera y se considera como un espejo más largo posible. Para evitar |como salida, solo se consideran las pilas no vacías.

xnor
fuente
2

Jalea , 17 bytes

ẆŒḂÐfṪœs2j”|µẋLḂ$

Pruébalo en línea!

Hecho con la ayuda del Sr. Xcoder y DJMcMayhem en el chat

Cómo funciona

ẆŒḂÐfṪœs2j”|µẋLḂ$ - Main link. Argument s  e.g.    ; 'AbbA'

Ẇ                 - All contiguous sublists
   Ðf             - Keep elements that are...
 ŒḂ               -  Palindromic                   ; [['A'], ['b'], ['b'], ['A'], ['bb'], ['AbbA']]
     Ṫ            - Final element                  ; 'AbbA'
      œs2         - Split into 2 chunks            ; ['Ab', 'bA']
         j”|      - Join with "|"                  ; 'Ab|bA'
            µ     - New link with ^ as argument
              LḂ$ - Is the length odd?             ; 1
             ẋ    - Repeat the string ^ many times ; 'Ab|bA'
caird coinheringaahing
fuente
1

Haskell, 126111 bytes

(!)=drop
f s|n<-length s=last$"":[a++'|':b|k<-[1..n],t<-map(!s)[1..n-k],let[a,b]=take k<$>[t,k!t],a==reverse b]
Lynn
fuente
1

TSQL 227 223 bytes

Codifiqué la longitud a un máximo de 99 bytes, esto guardó bytes pero lo hice más lento. Sin embargo, todavía tiene un rendimiento decente.

Golfizado:

DECLARE @t varchar(99)='AbccbA'

,@z char(99)='',@a INT=0,@ INT=0WHILE @a<LEN(@t)SELECT
@z=IIF(LEN(x)>LEN(@z)/2and @t LIKE'%'+x+REVERSE(x)+'%'COLLATE
Thai_bin,x+'|'+REVERSE(x),@z),@=IIF(@=50,1,@+1),@a+=IIF(@=1,1,0)FROM(SELECT
SUBSTRING(@t,@a,@)x)x PRINT @z

Sin golf:

DECLARE @t varchar(99)='AbccbA'

,@z char(99)='',
@a INT=0,
@ INT=0
WHILE @a<LEN(@t)
  SELECT
    @z=IIF(LEN(x)>LEN(@z)/2and @t LIKE'%'+x+REVERSE(x)+'%'COLLATE Thai_bin,x+'|'
       +REVERSE(x),@z),
    @=IIF(@=99,1,@+1),
    @a+=IIF(@=1,1,0)
  FROM
    (SELECT SUBSTRING(@t,@a,@)x)x

PRINT @z

Violín

t-clausen.dk
fuente
1
Puede reducir 2 bytes si limita a 99, ya que el último ejemplo tiene solo 99 caracteres de largo
Alex Carlsen
1
@VisualBean gracias, cambió el script para permitir solo 99 caracteres, también cambió la clasificación de Thai_CS_AS a thai_bin
t-clausen.dk
0

Python 2, 149 bytes

R,L,s=range,len,input()
t=max([s[i:j/2+i/2]for i in R(L(s))for j in R(L(s)+1)if s[i:j]==s[i:j][::-1]and(j-i)%2<1],key=L)
print t+'|'*(L(t)>0)+t[::-1]

Pruébalo en línea

Este programa encuentra la primera mitad de la subcadena palindrómica más grande de longitud par, e imprime esa cadena, seguida de una |, seguida de esa cadena invertida. Si no hay una cadena adecuada, tserá la cadena vacía y '|'*(L(t)>0)se evaluará a la cadena vacía.

Mego
fuente
0

Java 8, 294 283 232 bytes

s->{int l=s.length(),i=0,j,z,y=0;String a,b="";for(;i<l;i++)for(j=0;j<=l-i;)if((a=s.substring(i,i+j++)).equals(new StringBuffer(a).reverse()+"")&(z=a.length())%2<1&z>y){y=z;b=a;}return y>0?b.substring(0,y/=2)+"|"+b.substring(y):"";}

Explicación:

Pruébalo aquí.

s->{                               // Method with String as both parameter and return-type
  int l=s.length(),                //  Length of the input-String
      i=0,j,                       //  Index-integers
      z,y=0;                       //  Temp-integers
  String a,b="";                   //  Temp-Strings
  for(;i<l;i++)                    //  Loop (1) from 0 to `l` (exclusive)
    for(j=0;j<=l-i;                //   Inner loop (2) from 0 to `l-i` (inclusive)
      if((a=s.substring(i,i+j++))  //    Set the current substring to `a`
          .equals(new StringBuffer(a).reverse()+"")
                                   //    If `a` is a palindrome
         &(z=a.length())%2<1       //    And the length of `a` is even
         &z>y){                    //    And the length of `a` is larger than `y`
        y=z;                       //     Change `y` to `z`
        b=a;}                      //     Change `b` to `a`
                                   //   End of inner loop (2) (implicit / single-line body)
                                   //  End of loop (1) (implicit / single-line body)
  return y>0?                      //  If the result-length is not 0:
    b.substring(0,y/=2)+"|"+b.substring(y)
                                   //   Return the result
   :                               //  Else:
    "";                            //   Return an empty String
}                                  // End of method
Kevin Cruijssen
fuente