Вступление
Я не вижу много проблем с регулярными выражениями здесь, поэтому я хотел бы предложить этот обманчиво простой, который может быть выполнен несколькими способами с использованием ряда разновидностей регулярных выражений. Я надеюсь, что это даст любителям регулярных выражений немного времени для игры в гольф.
Вызов
Задача состоит в том, чтобы сопоставить то, что я очень слабо назвал «эгалитарной» серией: серией равного числа разных персонажей. Это лучше всего описано на примерах.
Совпадение:
aaabbbccc
xyz
iillppddff
ggggggoooooollllllffffff
abc
banana
Не совпадают:
aabc
xxxyyzzz
iilllpppddff
ggggggoooooollllllfff
aaaaaabbbccc
aaabbbc
abbaa
aabbbc
Обобщать, мы хотим , чтобы соответствовать теме формы ( для любого списка символов в , где для всехc1)n(c2)n(c3)n...(ck)n
c1
ck
ci != ci+1
i, k > 1, and n > 0.
Разъяснения:
Ввод не будет пустым.
Символ может повториться позже в строке (например, «банан»)
k > 1
, поэтому в строке всегда должно быть как минимум 2 разных символа.Вы можете предположить, что в качестве входных данных будут передаваться только символы ASCII, и ни один символ не будет символом конца строки.
правила
(Спасибо Мартину Эндеру за этот превосходно сформулированный блок правил)
Ваш ответ должен состоять из одного регулярного выражения без какого-либо дополнительного кода (за исключением, необязательно, списка модификаторов регулярного выражения, необходимых для работы вашего решения). Вы не должны использовать функции своего языка регулярных выражений, которые позволяют вам вызывать код на языке хостинга (например, e
модификатор Perl ).
Вы можете использовать любой аромат regex, который существовал до этого испытания, но, пожалуйста, укажите аромат.
Не думайте, что регулярное выражение неявно привязано, например, если вы используете Python, предположите, что ваше регулярное выражение используется с re.search, а не с re.match. Ваше регулярное выражение должно соответствовать всей строке для правильных эгалитарных строк и не давать совпадений для недопустимых строк. Вы можете использовать столько групп захвата, сколько пожелаете.
Вы можете предположить, что ввод всегда будет строкой из двух или более символов ASCII, не содержащих разделителей строки.
Это рег-гольф, поэтому выигрывает самое короткое в байтах. Если ваш язык требует разделителей (обычно /.../
) для обозначения регулярных выражений, не считайте сами разделители. Если вашему решению требуются модификаторы, добавьте один байт на каждый модификатор.
критерии
Это хороший старомодный гольф, поэтому забудьте об эффективности и постарайтесь сделать ваше регулярное выражение как можно меньше.
Пожалуйста, укажите, какой вкус regex вы использовали, и, если возможно, включите ссылку, показывающую онлайн-демонстрацию вашего выражения в действии.
banana
которое эгалитарно.Ответы:
.NET аромат, 48 байт
Попробуйте онлайн! (используя Retina )
Что ж, получается, что не отрицать логику все- таки проще. Я делаю это отдельным ответом, потому что два подхода совершенно разные.
объяснение
источник
((^.|\2(?=.*\4\3)|\4(?!\3))(?=\2*+((.)\3?)))+\3$
я экспериментировал\3*
вместо того,(?!\3)
чтобы сделать его 45b, но это не сработало на «aabbbc» :( Версия Perl легче понять, и теперь она меньше 45b:^((?=(.)\2*(.))(?=(\2(?4)?\3)(?!\3))\2+)+\3+$
- причина, по которой я называю это Perl, хотя она Кажется, что действительным PCRE является то, что PCRE думает, что(\2(?4)?\3)
может возвращаться бесконечно, тогда как Perl немного умнее / прощает!.NET аромат, 54 байта
Попробуйте онлайн! (используя Retina )
Я почти уверен, что это неоптимально, но это лучшее, что я придумаю для балансировки групп прямо сейчас. У меня есть одна альтернатива с тем же количеством байтов, которое в основном такое же:
объяснение
Основная идея состоит в том, чтобы перевернуть проблему, сопоставить неэгалитарные строки и поставить все это в негативную перспективу, чтобы свести на нет результат. Преимущество заключается в том, что нам не нужно отслеживать n во всей строке (поскольку из-за природы групп балансировки вы обычно используете n при проверке), чтобы проверить, что все прогоны имеют одинаковую длину. Вместо этого мы просто ищем одну пару смежных трасс, которые не имеют одинаковую длину. Таким образом, мне нужно только использовать п раз.
Вот разбивка регулярного выражения.
источник
banana
,aba
,bbbaaannnaaannnaaa
,bbbaaannnaaannnaaaaaa
,The Nineteenth Byte
,11
,110
,^(?!.*(?<=(\2)*(.))(?!\2)(?>(.)(?<-1>\3)*)(?(1)|\3)).+
,bababa
. Это я потерпел неудачу. :( +1