Onde devo colocar meu espelho?


30

Este é um espelho: |. Acabei de descobrir que você pode colar um espelho no meio de uma string se a string puder ser espelhada em si mesma! Por exemplo, a sequência abccba. Se você cortá-lo ao meio, as duas metades são imagens espelhadas uma da outra:

abc  <-->  cba

Então, podemos colocar um espelho no meio da string, e nossa nova string é abc|cba. Às vezes, apenas parte da cadeia pode ser espelhada em si mesma. Por exemplo, a cadeia "espelho". Os dois r's são espelhados, mas o resto da string não é. Tudo bem, apenas removeremos as partes da sequência que não se espelham e obteremos a seguinte sequência:

r|r

Algumas seqüências de caracteres podem ser espelhadas em vários lugares. Por exemplo, "Olá, mundo, xyzzyx". Eu gosto de ter muito texto refletido no meu espelho, então você precisa encontrar o melhor lugar para colocar o meu espelho. Nesse caso, você deve gerar a string espelhada mais longa e, como no nosso último exemplo, remover todo o resto. Essa sequência se torna:

xyz|zyx

Algumas seqüências parecem poder ser espelhadas, mas na verdade não podem. Se uma sequência não puder ser espelhada em nenhum lugar, você não deverá produzir nada.

O desafio:

Dada uma string contendo apenas ascii imprimíveis, encontre o melhor lugar para colocar meu espelho. Em outras palavras,

Encontre a maior substring palindrômica de tamanho uniforme e, em seguida, imprima-a com um caractere de pipe '|' no meio disso.

A entrada terá de 1 a 50 caracteres.

Você pode assumir que a entrada não conterá espelhos |ou novas linhas. Além disso, todos os personagens imprimíveis-ascii são um jogo justo. Se a subseqüência espelhada mais longa estiver ligada entre duas subseqüências, você poderá escolher qual delas produzirá. Por exemplo, para a cadeia "abba ollo", você deve gerar "ab | ba" ou "ol | lo", mas não importa qual deles você produz. As strings diferenciam maiúsculas de minúsculas, por exemplo, "ABba" não deve gerar "AB | ba", deve gerar a string vazia.

IO de amostra:

"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 costume, isso é código-golfe, então as brechas padrão se aplicam e a resposta mais curta em bytes vence!


Existe um limite para o comprimento da entrada?
Mego

@Mego Desde que o seu algoritmo funcione teoricamente em qualquer entrada, não me importo quanto tempo leva / quanta memória é necessária.
DJMcMayhem

Perguntei porque os mecanismos regex baunilha são capazes apenas de combinar palíndromos de comprimento até um valor finito especificado (em oposição aos palíndromos arbitrariamente longos), e a possibilidade de uma solução baseada em regex dependeria da existência ou não de um valor superior limitado ao comprimento da entrada.
Mego

@ Mega Ah, isso faz sentido. Digamos que a entrada possa ter até 50 caracteres. Como isso soa?
DJMcMayhem

Respostas:


9

Pitão - 19 17 15 13 bytes

Obrigado a @FryAmTheEggman por me salvar dois bytes.

ARRGH o caso especial para nenhuma resposta. Resolvido isso!

e_I#jL\|cL2.:

Conjunto de Teste .

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.

2
Nao! Ninja'd para a resposta pyth; _;
Downgoat 04/07/19

Explicação, por favor? : 3
Downgoat 04/07

@Downgoat ele tomou todas as substrings e pique em dois, junte-se cada par com |, filtro por simetria, acréscimo que para [k] e obter o último elemento (que é o mais longo)
busukxuan

@Downgoat done.
Maltysen 04/07/19

2
:Q)= Bignose
gcampbell

8

05AB1E , 19 17 14 bytes

Código:

Œévy2ä'|ý©ÂQi®

Explicação:

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

Usa a codificação CP-1252 . Experimente online! .


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)

Bastante lento e ineficiente ... Verifique os casos de teste menores no Ideone .


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:""')

ou

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

Apenas curioso, para que serve eval?
Gcampbell 04/07/19

@gcampbell evalpara evitarreturn
edc65

Você não pode usar o operador de vírgula para evitar o retorno?
MayorMonty

@SpeedyNinja nope. fornão é uma expressão, por isso, normalmente, requerem chaves e umreturn
jrich


2

Retina , 66 bytes

A contagem de bytes assume a codificação ISO 8859-1.

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

Experimente online! (A primeira linha permite testar vários casos de teste separados por avanço de linha de uma só vez.)

Hmmm, muito mais tempo do que eu gostaria ...


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 golfe

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

Teste

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+')':'')
})  


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$_

Eu só queria experimentar regexes recursivas. Precisa da -popção. Edit: Salvo (riscado 4) 7 bytes graças a @ msh210. (O byte ausente deve-se a uma economia que foi substituída pela última economia de @ msh210.)


Eu não testei nenhum deles, mas provavelmente isso pode ser abreviado de várias maneiras, incluindo: (1) @_=(@_,$1)pode ser push@_,$1. (2) Omita as novas linhas e a final ;. (3) Eu suspeito que há uma condição de ordenação mais curto que você pode usar (se nada mais, pelo menos --- --- talvez substituto -para <=>)
msh210

@ msh210 Obrigado pelos dois primeiros pontos, mas eu já tentei -e não funcionou (provavelmente precisa de parênteses de precedência, o que prejudica a economia).
Neil

Tente y...c>>1ou em y...c/2vez de length>>1. (Não testado.)
msh210 04/07

@ msh210 Eu, obviamente, deve ter ler as dicas para jogar golfe em Perl primeiro ...
Neil

Acho que seu último par de parênteses também pode ir.
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)

Substitua \x7fpelo caractere real DEL, que é ASCII 127 (crédito para Dennis).

Isso segue uma estratégia semelhante à resposta de Dennis de usar maxe ramificar recursivamente para encontrar o intervalo palíndromo mais longo. Mas, em vez disso, encontra a metade esquerda, verificando se a metade direita espelhada correspondente vem logo depois com uma partida feita por ele mesmo .

A função adivinha se o primeiro caractere está na metade esquerda espelhada. Caso contrário, ele simplesmente o solta e se repete no restante. Se for, é adicionado à pilha pde caracteres invertidos. Se a sequência de caracteres começar com a pilha, a sequência de espelhos será gerada e considerada como um espelho mais longo possível. Para evitar |como saída, apenas pilhas não vazias são consideradas.


2

Geléia , 17 bytes

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

Experimente online!

Feito com a ajuda do Sr. Xcoder e DJMcMayhem no chat

Como 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'

1

Haskell, 126 111 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]

1

TSQL 227 223 bytes

Eu codifiquei o comprimento para no máximo 99 bytes, isso salvou os bytes, mas o tornei mais lento. Ainda tem um desempenho decente.

Golfe:

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

Ungolfed:

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

Violino


1
Você pode raspar 2 byte se limitar a 99 como o último exemplo é apenas 99 caracteres de comprimento
Alex Carlsen

1
@VisualBean thankyou, mudou o roteiro para permitir que apenas 99 caracteres, também mudaram o agrupamento de Thai_CS_AS para 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]

Experimente online

Este programa encontra a primeira metade da maior substring palindrômica de comprimento par e imprime essa sequência, seguida de a |, seguida pela sequência invertida. Se não houver uma sequência adequada, tserá a sequência vazia e '|'*(L(t)>0)será avaliada como a sequência vazia.


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):"";}

Explicação:

Experimente aqui.

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
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.