Неважко описати машину з кінцевим станом, яка розпізнає кратні цифри 9: слідкуйте за цифрою суми (мод 9) і додайте ту цифру, яку приймається далі. Така FSM має лише 9 станів, дуже просто! За еквівалентністю FSM-розпізнаваності та регулярних мов існує регулярний вираз для кратних 9. Однак будь-який такий регулярний вираз, ймовірно, ... дуже ... довгий. Як і в, ймовірно, на замовлення гігабайт.
На прикладі https://www.quaxio.com/triple/ є множини 3. Внизу сторінки автор пропонує дещо "оптимізоване вручну" рішення, яке трохи коротше, ніж наївне перетворення з FSM до регулярного вираження.
Змагання:
Ви повинні зробити регулярний вираз, щоб виявити кратні 9. Оскільки очікується, що такий регулярний вираз буде дуже довгим, я прошу надати програму, яка може роздрукувати ваш регулярний вираз. (Якщо ви дійсно хочете дати цілий регулярний вираз, можливо, розмістіть його в іншому місці та зв’яжіть його тут!)
Ви повинні бути в змозі сказати нам точну кількість символів виходу вашої програми - тому мати програму, яка просто намагається виконати всі регулярні вирази до певної довжини, поки не знайде той, що працює, неприйнятна, якщо вона не працює досить швидко, щоб ви могли запустіть його до завершення і дайте нам отриману довжину регулярного виразів!
Бали за те, що мають найкоротший вихідний регулярний вираз, звичайно не залежно від тривалості програми. Оскільки регулярний вираз - це "програма", про яку я прошу, і це занадто довго, щоб зручно передавати тут, я все-таки помічаю цей код-гольф.
Правила:
- Вхід буде містити лише відповідність символів
[0-9]*
. - Ваш регулярний вираз повинен відповідати кратним 9, але нічого іншого. Справи, які не складаються повністю з цифр 0-9 і є недійсними введеннями, можуть збігатися або виходити з ладу за вашим бажанням.
- Враховуючи мотивацію, що DFA легко розпізнається, отриманий регулярний вираз повинен бути фактичним регулярним виразом у більш теоретичній термінології, тобто лише операторах, під якими закриті регулярні мови. Якщо бути точним, дозволено лише:
- Літералів діапазони символів (
[ab]
,[a-f]
,[^k]
), клініевская зірка (*
), якір (^
і$
), угруповання з допомогою дужок, чергування (|
), необов'язкові терміни (?
), одно- або-більш термінів (+
), lookaheads ((?=)
), негативних lookaheads ((?!)
), lookbehinds ((?<=)
), негативний lookbehinds ((?<!)
), conditionals (як у https://www.regular-expressions.info/conditional.html -(?(?=test)then|else)
) та зворотні відношення обмеженої довжини (див. нижче).
- Літералів діапазони символів (
- Приклади речей, які НЕ допускаються:
- Зворотні параметри довільної довжини, прямі посилання, Рекурсія, підпрограми, циклічні конструкції, виконуваний код, будь-які зміни 'eval' або вбудовані конструкції для відведення рядка до арифметичного значення.
- Зворотні параметри, для яких може бути показано, що вони мають рядки з обмеженою довжиною, є прийнятними, оскільки вони можуть зберігатися у кінцевому стані і не змінювати регулярність мови. Наприклад, регулярний вираз
(..2.[3-5])4\1.\1
є прийнятним, оскільки на групі захоплення є обмежена довжина\1
. Це звичайне будівництво. Така конструкція(2*)0\1
неприйнятна, оскільки захоплена група не може зберігатися у кінцевому стані. - Ваш регулярний вираз може вільно приймати або відхиляти цілі числа із сторонніми провідними нулями за вашим бажанням. Однак рядок
"0"
потрібно прийняти.
^(0|9|(?<c>1|(?<c>2|(?<c>3|(?<c>4|(?<c>5|(?<c>6|(?<c>7|(?<c>8))))))))((?<-c>){9})?)*$(?(c).)