Коренастый палиндром

15

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

Например, строка "abcabca"не является палиндромом, если мы читаем ее символ за символом, но у нас есть три различных способа сделать ее коротким палиндромом:

["abcabca"]
["a" "bcabc" "a"]
["a" "bc" "a" "bc" "a"]

Как видите, коренастая палиндромность - это очень всеобъемлющее понятие; каждая строка может быть превращена в коренастый палиндром хотя бы одним способом.

задача

Напишите программу или функцию, которая получает строку в качестве входных данных и возвращает ее палиндромный массив , т. Е. Количество его разделов, которые являются палиндромными массивами.

Контрольные примеры

 OUTPUT | INPUT
--------+---------------------------------------------
      1 | ""                                          
      1 | "a"                                         
      1 | "ab"                                        
      2 | "aa"                                        
      2 | "aaa"                                       
      3 | "abcabca"                                   
      4 | "abababab"                                  
     28 | "abcabcaabababababcabca"                    
      1 | "bbbbabababbbbababbbaaaaa"                  
     20 | "ababbaaaabababbbaaabbbaa"                  
      5 | "baaabaabababaababaaabbaab"                 
     62 | "bbaaababbabbabbbabaabaabb"                 
      2 | "a man a plan a canal panama"               
     25 | "ama nap lan aca nal pan ama"               
     93 | "SATOR   AREPO   TENET   OPERA   ROTAS"     
    976 | "abcabcaabcabcaabcabcaabcabcaabcabcaabcabca"
  28657 | "ababababababababababaababababababababababa"
2097152 | "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"

Дополнительные правила

  • Вы можете предполагать, что ввод будет состоять из 42 или менее печатных символов ASCII, опционально окруженных разделителями строк вашего языка и / или сопровождаемых новой строкой.

  • Для каждой допустимой входной строки ваш код должен завершиться менее чем за одну минуту на моем компьютере (Intel Core i7-3770, 16 ГБ ОЗУ, Fedora 21).

    С адекватным алгоритмом должно быть легко соответствовать этому временному пределу. Однако вы, скорее всего, не сможете перебирать все разделы входной строки.

  • Если вы решите распечатать вывод в STDOUT, за ним может следовать одна новая строка.

  • Применяются стандартные правила .

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

Ответы:

4

Pyth, 40 34 27 22 байта

Lhsmy:bd_df!xb>TbS/lb2

Попробуйте это в онлайн-переводчике .

Сильно проиграл от начальной 40-байтовой версии. Спасибо FryAmTheEggman за указание на пару полезных операторов (документы трудно найти!), Которые сэкономили мне всего 6 байт. Спасибо Деннису за умелое сохранение одного байта, интерпретируя результат xкак истинное / ложное значение, а не как индекс, !xb>Tbа не как q<bT>Tb.


Как это устроено:

Мы определяем функцию, yкоторая определяет размер строки b, рекурсивно вызывая себя на подстроки b. Функции автоматически запоминаются в Pyth, поэтому рекурсия требует очень мало времени.

L                              def y(b): return ___
                 S/lb2         The range [1,2,...,len(b)/2]
          f!xb>Tb              Filter n for which b[:n] == b[-n:]
   m                           Map each n in the list to...
    y:bd_d                     y(b[d:-d])       
 hs                            Take the sum and add one (implicit return)
Сэм Кэпплман-Линс
источник
Да, большая часть изучения Pyth - это общение / проба и ошибка / чтение лексера, отличная работа с гольфом! :)
FryAmTheEggman
1
1. Вы можете сохранить два байта, отправив функцию. Там нет необходимости называть это с yz. 2. Вместо двух карт и фильтра вы можете использовать одну карту и условную ( ссылку ), которая сохраняет три байта.
Деннис
2

CJam ( 41 39 байт)

qM{_,2/,\f{\~_2$>@2$<@~)/(@=\M*j*}1b)}j

Онлайн демо

Это «нетерпение» в том смысле, что оно находит количество длинных палиндромов для каждой «центральной» строки (т. Е. Результат удаления одинакового количества символов с обоих концов исходной строки), но потому, что оно использует автозаписывание jОператор каждого вычисляется только один раз, давая очень быструю программу (и сохраняя несколько символов в незапамятной реализации).

Спасибо Деннису за сохранение одного байта.

Питер Тейлор
источник
1

Mathematica, 77 72 57 байт

1+Tr[#0/@ReplaceList[#,{a__,b___,a__}:>{b}]]&@*Characters
alephalpha
источник
1

Perl, 86 байт

Код 84 байта + 2 переключателя

Должен быть более короткий метод, но здесь идет:

perl -lpe 'sub c{my($x,$i)=@_;$x=~/^(.{$i})(.*)\1$/&&c($2,0*++$s)while++$i<length$x}c$_;$_=++$s'

Принимает ввод из STDIN, по одной строке на строку.

Объяснение: Для значений 1<=$i<length(input string)используется регулярное выражение /^(.{$i})(.*)\1$/для получения левого и правого фрагментов и увеличения счетчика. Затем рекурсивно делает то же самое для центральной части строки.

svsd
источник