Збірка реджексів (Заміна)


21

Ваше завдання - скласти регекси ..., вказавши підстановку для кожного символу в регулярному виразі.

Регекси

Регекси підтримують це

REGEX       = (LITERAL REGEX / GROUP REGEX / STAR REGEX / ALTERNATIVE)
LITERAL     = 1 / 0
GROUP       = '(' REGEX ')'
STAR        = (LITERAL / GROUP) '*'
ALTERNATIVE = '('REGEX ('|' REGEX)*')'

Чому лише 1 або 0? Це для спрощення. Таким чином, регулярний вираз має лише такі символи:

*()|10

Він тлумачиться так:

  1. * є зірка Клейна (повторити ліву групу або буквально 0 і більше разів).
  2. | - це чергування (збігається, якщо регекс ліворуч або регекс праворуч відповідає).
  3. () є групуванням.
  4. 1 відповідає символу 1.
  5. 0 відповідає символу 0.

Як скласти?

Ви вказуєте шість фрагментів коду: один для заміни кожного символу регулярного вираження. Наприклад, якщо ваша відповідь:

*: FSAGFSDVADFS
|: GSDGSAG
(: GSDG
): GDSIH
1: RGIHAIGH
0:GIHEBN

Потім ви замінюєте кожен регулярний вираз на відповідний фрагмент коду, таким чином:

(0|11)*

перетворюється на:

GSDGGIHEBNGSDGSAGRGIHAIGHRGIHAIGHGDSIHFSAGFSDVADFS

Що слід зробити програмою?

Ваша програма:

  1. Візьміть вхід.
  2. Виведіть триєдне значення, якщо регулярний вираз збігається з цілим входом.
  3. В іншому випадку вивести помилкове значення.

Вхід назовні 01- це обмежена невизначена поведінка. Введення може бути порожнім.

Додаткові правила

  1. Для заданого символу регулярного вираження отриманий фрагмент повинен бути завжди однаковим.
  2. Після цього жодного символу префікса чи суфікса не додано.
  3. Зрозуміло, що регулярний вираз не буде порожнім.

Оцінка балів

Найменш комбінований фрагмент - переможець. Тож оцінка для прикладу буде розрахована так:

FSAGFSDVADFS+ GSDGSAG+ GSDG+ GDSIH+ RGIHAIGH+GIHEBN

12 + 7 + 4 + 5 + 8 + 6 = 42


Чи повинен кожен фрагмент мати принаймні 1 символ?
трихоплакс

Фрагмент може мати нульову довжину. Редагування в порядку.
Акангка

Чи дійсна мова RegEx для цього завдання? : P
Loovjo

Я вважаю, що в RegEx є вбудована RegEx. Я змушений це робити. Хочу виключити сітківку та регекс, однак, за словами Мего, це не дозволено. Досі я не знаю про Равликів та друзів.
Акангка

@ChristianIrwan Цікаво, що я все ще не впевнений, що це навіть вирішити у Retina, і навіть це так, це буде далеко не конкурентоспроможним.
Мартін Ендер

Відповіді:


7

Равлики , 48 байт

0 -> )0(\0!(l.)(~

1 -> )0(\1!(l.)(~

( -> )0({{(

) -> )0}}(~

| -> )0}|{(

* -> )0),(~

Якби нам довелося шукати часткові збіги, а не відповідати лише повним введенням, то це було б дуже просто. 0став би \0, 1став би \1, *став би ,, а решта відображалися б собі. Натомість є багато шнаніганів, які не дозволяють матчам починати десь інше, ніж початок чи закінчуватись десь, крім кінця. !(l.)це твердження, яке не вдасться, якщо початок збігу не буде на початку введення. ~відповідає клітинці поза введенням, тому вона додається до всіх символів, яким дозволено знаходитись в кінці регулярного вираження. Якщо слідує інший символ регулярного вираження, він скасовується числовим кількісним показником0що вимагає його зіставлення 0 разів, по суті, коментуючи це. Щоб дозволити *( ,) працювати коректно, незважаючи на те, що тест поза межі роботи не використовується, широко застосовуються правила відповідності дужок мови. З документації:

Збігаючі пари круглих дужок ()або фігурні дужки {}будуть вести себе як очікувалося (як дужки в регулярному вираженні), але також можна залишити половину пари і зробити це висновком відповідно до наступних правил. )або }згрупуйте все ліворуч до найближчої незакритої інструкції з відкриття групи того ж типу ( (або {відповідно) або до початку шаблону, якщо такої немає. Він закриває будь-які незакриті інструкції з відкриття протилежного типу в середині цього діапазону. Інакше не збігається (або {закривається кінцем шаблону.

Ясно, як грязь, правда?


Зітхаю, я забуваю, що за межами регулярного вираження є навіть відповідна мова. Хороша робота, але вибачте, ніяких оновлень (немає і жодної трансляції)
Akangka

@ChristianIrwan насправді є цілий виклик на цьому сайті щодо розробки 2d відповідних мов, більшість з яких має 1d вироджене використання. codegolf.stackexchange.com/questions/47311/…
Sparr

7

CJam, 151 байт

{]Na/Saf+{:m*:sSf-~}%}:J{+:MU{]W=~Jea&,}|}:TM0sa`T
{]Na/Saf+{:m*:sSf-~}%}:J{+:MU{]W=~Jea&,}|}:TM1sa`T
M{{+:M];eas!}:T}|U):UM'[T
MN`T
U(:UM'JT
M\"S+ea`,m*\"T

Рядки відповідають символам 01(|)*(у такому порядку). Спробуйте в Інтернеті!

При цьому не використовується вбудований регулярний вираз або інші типи відповідності шаблону. Насправді CJam не має жодної з цих особливостей. Натомість він починається з регулярного виразу, який він представляє, і будує всі можливі рядки, з якими він може відповідати, і нарешті перевіряє, чи є введення користувача одним із них.

Тестові прогони

Далі використовується програма, яка читає регулярний вираз із STDIN, замінює кожен його символ відповідним фрагментом і, нарешті, оцінює згенерований код, щоб побачити, чи відповідає він вхідному значенню аргументу командного рядка.

$ cat regex.cjam
l"01(|)*""

{]Na/Saf+{:m*:sSf-~}%}:J{+:MU{]W=~Jea&,}|}:TM0sa`T
{]Na/Saf+{:m*:sSf-~}%}:J{+:MU{]W=~Jea&,}|}:TM1sa`T
M{{+:M];eas!}:T}|U):UM'[T
MN`T
U(:UM'JT
M\"S+ea`,m*\"T

"N%ers~
$ cjam regex.cjam '' <<< '(|)'
1
$ cjam regex.cjam '0' <<< '(|)'
0
$ cjam regex.cjam '' <<< '0(|)'
0
$ cjam regex.cjam '0' <<< '0(|)'
1
$ cjam regex.cjam '' <<< '(0|11)*'
1
$ cjam regex.cjam '0' <<< '(0|11)*'
1
$ cjam regex.cjam '11' <<< '(0|11)*'
1
$ cjam regex.cjam '011011000' <<< '(0|11)*'
1
$ cjam regex.cjam '1010' <<< '(0|11)*'
0

На жаль, це не особливо швидко. Він задихнеться досить швидко, якщо на вводі буде більше 9 символів або більше однієї зірки Клінова.

Ціною 5 додаткових байтів - загалом 156 байт - ми можемо генерувати більш короткі рядки, щоб відповідати потенційним введенням та дедублювати їх. Це не змінює спосіб роботи коду; це просто робить його більш ефективним.

$ cat regex-fast.cjam 
l"01(|)*""

{]Na/Saf+{:m*:sSf-~}%}:J{+:MU{]W=~Jea&,}|}:TM0sa`T
{]Na/Saf+{:m*:sSf-~}%}:J{+:MU{]W=~Jea&,}|}:TM1sa`T
M{{+:M];eas!}:T}|U):UM'[T
MN`T
U(:UM'JT
M\"S+eas,)m*:sSf-L|\"T

"N%ers~
$ cjam regex-fast.cjam '0101001010' <<< '(01|10)*'
0
$ cjam regex-fast.cjam '011001101001' <<< '(01|10)*'
1
$ cjam regex-fast.cjam '0' <<< '(0*1)*'
0
$ time cjam regex-fast.cjam '101001' <<< '(0*1)*'
1

Я все ще маю уявлення, як я міг би зробити це коротшим та / або швидшим. Я додам пояснення, коли буду задоволений результатами.
Денніс

Здається, що `-escaping of the в шаблоні "" зайве "" *. Незалежно від цього, я не міг змусити цю програму приймати будь-які дані, навіть для найпростішого випадку, коли регулярний вимір складається лише з 0(див. Тест в онлайн-перекладачі ). Я роблю це неправильно?
мац

1
@matz Мій код використовує аргументи командного рядка, які не реалізовані в цьому інтерпретаторі. Спробуйте це замість цього.
Денніс
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.