IMP: нечіткий аналізатор множення


9

Джеку подобається мова програмування на C, але він ненавидить писати вирази, які люблять V=a*b*h; множити значення.

Він хотів би написати V=abh;замість цього, чому компілятор стогне про те, що abhсимвол не визначений, оскільки int a, b, h;вони визначені, щоб ми могли вивести множення?

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

Для простоти множення на число (як і в 2*a*b) не враховується, з'являються лише змінні.

Вхід є терміном множення T , що виконує regexp:

[a-zA-Z_][a-zA-Z_0-9]*

і змінне безліч Z .

Синтаксичний аналіз терміна T над набором змінної Z - це рядок, що відповідає наступному:

  1. після видалення всіх випадків *з P ми отримуємо T,
  2. або ім'я змінної від Z, або складається з власних імен змінних з Z, розділених на окремі *символи.

Рішення повинно надрукувати всі синтаксичні позначення терміна.

Зразок:

Vars           a, c, ab, bc
Term           abc
Solution       ab*c, a*bc

Vars           ab, bc
Term           abc
Solution       -

Vars           -
Term           xyz
Solution       -

Vars           xyz
Term           xyz
Solution       xyz

Vars           width, height
Term           widthheight
Solution       width*height

Vars           width, height
Term           widthheightdepth
Solution       -

Vars           aaa, a
Term           aaaa
Solution       aaa*a, a*aaa, a*a*a*a

Вхідні дані (перелік змінних та термін) можуть надаватися будь-яким способом, відповідним мові.

Вихід може бути в будь-якій розумній формі (один аналіз на рядок або список, розділений комами тощо) - але він повинен бути однозначним і можливим для читання.

Порожній вихід прийнятний, якщо неможливий розбір терміна (у прикладах, які я використав '-' для наочності).

Це кодовий гольф, тому виграє найкоротший код.


1
У вашому першому прикладі я вважаю ab*c, що це неправильний аналіз, оскільки cце не дозволена змінна.
isaacg

1
При рекурсивному скануванні я знаходжу саме ваш результат у вибірці. Але сумнівно: чому a*aaa aaa*aі ніab*c c*ab
edc65

Через правило 1. розбору. Так, множення зазвичай є комутативним, але ми не йдемо так далеко - ми просто хочемо "реконструювати" множення в тому порядку, як це було зроблено. Насправді в мові Джека ми могли мати матричний тип - множення не є комутативним тоді. І "aaaa" може бути як протиставленням "aaa", так і "a" або "a" і "aaa" - це не для комутативності, а для неоднозначності, яку ми беремо до уваги обох.
pawel.boczarski

Відповіді:


4

Піт, 18 ч

mj\*dfqzsTsm^Qkhlz

Це рішення адаптоване з мого розчину " Інтерпретація риби" Проблеми насправді дуже схожі.

Очікує введення як такого:

aaaa
"a", "aaa"

Дає вихід таким чином:

['a*aaa', 'aaa*a', 'a*a*a*a']

Спробуйте тут.

  • sm^Qkhlz: Створює всі послідовності змінних, що містять до довжини вхідного рядка кількість змінних.

  • fqzsT: Фільтрує змінні послідовності, що відповідають вхідному рядку

  • mj\*d: Вставляє *символ і відбитки.


3

Python 2 - 147 94 байт


R=lambda S,V,F=[]:S and[R(S[len(v):],V,F+[v])for v in V if v==S[:len(v)]]or print("*".join(F))

Це визначає функцію, Rяку слід використовувати:

>>> R("abc", ["a", "bc", "ab", "c"])

Друкує вихід:

a*bc
ab*c

1

JavaScript (ES6) 111

Пристосований з моєї відповіді «рибки» , головна відмінність - це пошук усіх рішень, не лише першого.

F=(v,t)=>(k=(s,r)=>s?v.map(v=>s.slice(0,l=v.length)==v&&k(s.slice(l),[...r,v])):console.log(r.join('*')))(t,[])

Вихід друкується на консоль. Результат функції не має жодного значення і повинен бути відкинутий.

Тест у консолі Firefox / FireBug

F(['a','c','ab','bc'],'abc')  
a*bc  
ab*c

F(['ab','bc'],'abc')

F(['aaa','a'],'aaaa')
aaa*a
a*aaa
a*a*a*a

F(['xyz'],'xyz')
xyz
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.