Проблема
У меня есть куча регулярных выражений, которые мне нужно использовать в некотором коде, но я использую язык программирования, который не поддерживает регулярные выражения! К счастью, я знаю, что тестовая строка будет иметь максимальную длину и будет состоять только из печатного ASCII.
Соревнование
Вы должны ввести регулярное выражение и число n
, и выход каждая строка состоит из печатной ASCII (ASCII коды от 32 до 126 включительно, до
~
, ни вкладок или перевода строки) длины меньше или равно n
что совпадает с регулярным выражением. Вы не можете использовать встроенные регулярные выражения или функции сопоставления регулярных выражений в вашем коде вообще. Регулярные выражения будут ограничены следующим:
- Литеральные символы (и escape-символы, которые заставляют символ быть буквальным,
\.
как и литерал.
,\n
являются литераломn
(эквивалентным простоn
) и\w
эквивалентныw
. Вам не нужно поддерживать escape-последовательности.) .
- подстановочный знак (любой символ)- Классы символов,
[abc]
означает «a или b или c» и[d-f]
означает что-нибудь от d до f (так, d или e или f). Единственными символами, которые имеют особое значение в классе символов, являются[
и]
(которые всегда будут экранированы, поэтому не беспокойтесь о них)\
(escape-символ, конечно)^
в начале класса символов (который является отрицанием). ) и-
(который является диапазоном). |
- оператор ИЛИ, чередование.foo|bar
означает либоfoo
илиbar
, и(ab|cd)e
соответствует либоabe
илиcde
.*
- сопоставить предыдущий токен, повторенный ноль или более раз, жадный (он пытается повторить столько раз, сколько возможно)+
- повторяется один или несколько раз, жадный?
- ноль или один раз- Группировка с помощью скобок, группировать жетоны
|
,*
.+
, или?
Вход регулярное выражение всегда будет действительным (то есть, вы не должны обрабатывать ввод как ?abc
или (foo
или любой неверный ввод). Вы можете выводить строки в любом порядке, который хотите, но каждая строка должна появляться только один раз (не выводить дубликаты).
Тестовые случаи
Вход: .*
, 1
выход: (пустая строка), ,
!
, "
, ..., }
,~
Вход: w\w+
, 3
выход: ww
,www
Вход: [abx-z][^ -}][\\]
, 3
выход: a~\
, b~\
, x~\
, y~\
,z~\
Вход: ab*a|c[de]*
, 3
выход: c
, cd
, ce
, aa
, cde
, ced
, cdd
, cee
,aba
Вход: (foo)+(bar)?!?
, 6
выход: foo
, foo!
, foofoo
,foobar
Вход: (a+|b*c)d
, 4
выход: ad
, cd
, aad
, bcd
, aaad
,bbcd
Вход: p+cg
, 4
выход: pcg
,ppcg
Вход: a{3}
, 4
выход:a{3}
Победитель
Это код-гольф , поэтому выиграет самый короткий код в байтах!
источник
|
имеет очень мало смысла. Кажется, он не обрабатывает вложенные группы илиa|b|c
. Что плохого в том, чтобы использовать стандартные объяснения с точки зрения того, насколько сильно связаны конкатенация и чередование? (И у вас нет оправданий для того, чтобы не использовать песочницу)Ответы:
Haskell
757 705 700 692 679667выход:
Пояснение: это реализация регулярного выражения в учебнике. R - это тип регулярного выражения с конструкторами A (альтернативный), L (буквальный), T (тогда) и E (пустой / эпсилон). Обычная «Звезда» не появляется, потому что во время разбора я добавляю ее как чередующиеся (см. «%»). m запускает симуляцию Парсер (начинающийся с 'rs = ....') - это просто рекурсивный спуск; 'k' разбирает диапазоны. Функция '#' расширяет диапазоны в чередования.
источник
Python v2.7
10691036950925897884871833822Этот ответ кажется довольно длинным для кода гольфа, но есть много операторов, которые должны быть обработаны, и я знаю, для чего предназначен каждый байт в этом ответе. Поскольку ответа не существует, я отправляю его в качестве цели для других пользователей. Посмотрим, сможешь ли ты сделать более короткий ответ :).
Две основные функции:
f
анализирует регулярное выражение, начинающееся сi
символа th, иd
генерирует соответствующие строки, используяr
под-регулярные выражения, в которые мы можем вернуться, 'a' массив, представляющий часть текущего под-регулярного выражения, еще не обработанную, и суффикс строки,s
представляющий часть сгенерированной строки.Также проверьте выход образца и тестовый жгут .
Обратите внимание, что вкладки в исходном решении были
expand
отредактированы. Для подсчета количества символов в оригинале используйтеunexpand < regex.py | wc
.источник
def E(a,b):c=a[:];c.extend(b);return c
наE=lambda a,b:a[:].extend(b)
, то жеA
elif isinstance(e,str):
, я полагаю, вы можете изменить код внутри:exec{'.':'for c in C:d(r,p,s+chr(c))','?':'d(r,p,s);d(r,p[:z],s)','*':'''c=p[:z]#newline for i in R(0,n+1):d(r,c,s);c+=[p[z]]''','+':"d(r,p+['*',p[z]],s)",'\\':'d(r,p,e[1]+s)'}.get(e,'d(r,p,e+s)')
(обратите внимание, что#newline
это новая строка) (источник: stackoverflow.com/a/103081/1896169 )