Где я должен положить свое зеркало?

30

Это зеркало |. Я только что узнал, что вы можете прикрепить зеркало в середине строки, если строка может быть отражена на себя! Например, строка abccba. Если разрезать его пополам, две половинки являются зеркальным отображением друг друга:

abc  <-->  cba

Таким образом, мы можем вставить зеркало в середине строки, и наша новая строка будет abc|cba. Иногда, только часть строки может быть отражена на себе. Например, строка «зеркало». Два r отражены, но остальная часть строки - нет. Это нормально, мы просто удалим части строки, которые не отражают друг друга, и получим следующую строку:

r|r

Некоторые строки могут быть отражены в нескольких местах. Например, «Hello World, xyzzyx». Мне нравится, когда в моем зеркале отражается много текста, поэтому вам нужно найти лучшее место, чтобы поставить мое зеркало. В этом случае вы должны вывести более длинную зеркальную строку и, как и в нашем последнем примере, удалить все остальное. Эта строка становится:

xyz|zyx

Некоторые строки выглядят так, как будто они могут быть отражены, но на самом деле не могут. Если строка нигде не отражается, вы ничего не должны выводить.

Соревнование:

Учитывая строку, содержащую только printable-ascii, найдите лучшее место для размещения моего зеркала. Другими словами,

Найдите наибольшую палиндромную подстроку четной длины, затем выведите ее с символом трубы '|' в середине этого.

Длина ввода будет 1-50 символов.

Вы можете предположить, что ввод не будет содержать зеркал |или новых строк. Кроме того, все печатные символы ascii являются честной игрой. Если самая длинная зеркальная подстрока связана между двумя подстроками, вы можете выбрать, какую из них вывести. Например, для строки «abba ollo» вы должны вывести «ab | ba» или «ol | lo», но не имеет значения, какую вы выводите. Строки чувствительны к регистру, например, «ABba» не должен выводить «AB | ba», он должен выводить пустую строку.

Образец ввода-вывода:

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

Как обычно, это код-гольф, поэтому применяются стандартные лазейки, и выигрывает самый короткий ответ в байтах!

DJMcMayhem
источник
Есть ли ограничение на длину ввода?
Мего
@Mego Пока ваш алгоритм теоретически работает на любом входе, мне все равно, сколько времени это займет и сколько памяти.
DJMcMayhem
Я спросил, потому что ванильные движки регулярных выражений способны сопоставлять только палиндромы длины до заданного конечного значения (в отличие от произвольно длинных палиндромов), и возможность решения на основе регулярных выражений будет зависеть от того, существует ли верхний ограничено длиной входа.
Мего
@Mego Ах, это имеет смысл. Допустим, ввод может быть длиной до 50 символов. Как это звучит?
DJMcMayhem

Ответы:

9

Pyth - 19 17 15 13 байт

Спасибо @FryAmTheEggman за то, что сэкономили мне два байта.

ARRGH особый случай без ответа. Решил это!

e_I#jL\|cL2.:

Тестовый пакет .

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
источник
2
Нееет! Ninja'd к pyth ответ; _;
Вниз
Пояснения пожалуйста? : 3
Downgoat
@Downgoat он взял все подстроки и разделил на две части, соединил каждую пару с |, отфильтровал по симметрии, добавил это к [k] и получил последний элемент (самый длинный)
busukxuan
@ Downgoat сделано.
Maltysen
2
:Q)= Bignose
gcampbell
8

05AB1E , 19 17 14 байтов

Код:

Œévy2ä'|ý©ÂQi®

Объяснение:

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

Использует кодировку CP-1252 . Попробуйте онлайн! ,

Аднан
источник
5

Python 2, 102 97 байт

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)

Скорее медленно и неэффективно ... Проверьте меньшие контрольные примеры на Ideone .

Деннис
источник
4

JavaScript, 100 99 байт

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

или

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
источник
Просто любопытно, для чего eval?
Гэмпбелл
@gcampbell, evalчтобы избежатьreturn
edc65
Разве вы не можете использовать оператор запятой, чтобы избежать возврата?
MayorMonty
@SpeedyNinja Нету. forне является выражением, так что , как правило , требуют фигурных скобок иreturn
jrich
2

Сетчатка , 66 байт

Количество байтов предполагает кодировку ISO 8859-1.

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

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

Хм, намного дольше, чем хотелось бы ...

Мартин Эндер
источник
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

Меньше гольфа

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

Тест

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
источник
2

Perl 5, 105 100 98 + 1 = 106 101 99 байт

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

Я просто хотел попробовать рекурсивные регулярные выражения. Нужен -pвариант. Редактировать: Сохранено (вычеркнуто 4) 7 байтов благодаря @ msh210. (Отсутствующий байт вызван сохранением, которое было заменено последним сохранением @ msh210.)

Нил
источник
Я не проверял ни одного из них, но, вероятно, это может быть сокращено различными способами, в том числе: (1) @_=(@_,$1)может быть push@_,$1. (2) Опустить переводы строки и финал ;. (3) Я подозреваю , что есть более короткое условие сортировки можно использовать (если ничего другого , то , по крайней мере --- возможно --- заменить -на <=>)
msh210
@ msh210 Спасибо за первые два пункта, но я уже попробовал, -и это не сработало (вероятно, нужны скобки для приоритета, который побеждает экономию).
Нил
Попробуй y...c>>1или y...c/2вместо length>>1. (Не проверено.)
msh210
@ msh210 Я, очевидно, должен был сначала прочитать советы по игре в гольф на Perl ...
Нил
Полагаю, твои последние пары тоже могут пойти.
msh210
2

Python 2, 91 байт

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)

Замените \x7fдействительным символом DEL, который является ASCII 127 (кредит Деннису).

Это следует стратегии, аналогичной ответу Денниса об использовании maxи рекурсивном ветвлении, чтобы найти самый длинный интервал палиндрома. Но вместо этого он находит левую половину, проверяя, что соответствующая зеркальная правая половина идет сразу после нее с самодельным запуском с .

Функция определяет, находится ли первый символ в зеркальной левой половине. Если нет, он просто отбрасывает его и возвращается к остатку. Если это так, он добавляется в стек pобращенных символов. Если строка когда-либо начинается со стека, строка зеркала генерируется и рассматривается как возможное самое длинное зеркало. Чтобы избежать |в качестве вывода, рассматриваются только непустые стеки.

XNOR
источник
2

Желе , 17 байт

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

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

Сделано с помощью мистера Xcoder и DJMcMayhem в чате

Как это работает

ẆŒḂÐ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 Coneheringaahing
источник
1

Haskell, 126 111 байтов

(!)=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 байта

Я жестко закодировал длину до 99 байтов, это сохранило байты, но сделало их медленнее. Это все еще имеет достойную производительность, хотя.

Golfed:

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

скрипка

t-clausen.dk
источник
1
Вы можете сбрить 2 байта, если ограничить до 99, поскольку последний пример имеет длину только 99 символов
Алекс Карлсен
1
@VisualBean спасибо, изменил сценарий, чтобы разрешить только 99 символов, также изменил сопоставление с Thai_CS_AS на thai_bin
t-clausen.dk
0

Python 2, 149 байт

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]

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

Эта программа находит первую половину самой большой палиндромной подстроки четной длины и печатает эту строку, после которой следует символ «а» |, а затем строка в обратном порядке. Если подходящей строки нет, tбудет пустой строкой и '|'*(L(t)>0)будет оцениваться в пустой строке.

Mego
источник
0

Java 8, 294 283 232 байта

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

Объяснение:

Попробуй это здесь.

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
Кевин Круйссен
источник