IMP: неявный анализатор умножения


9

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

Он хотел бы написать V=abh;Вместо этого , почему компилятор должен стонать о том, что abhсимвол не определен, поскольку он int a, b, h;определен, чтобы мы могли выводить умножение?

Помогите ему реализовать синтаксический анализатор, который расшифровывает один термин умножения, при условии, что набор переменных, определенных в текущей области видимости, известен.

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

Вводом является умножение T , выполняющее регулярное выражение:

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

и набор переменных Z .

Синтаксический анализ P термина 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это недопустимая переменная.
Исаак

1
С помощью рекурсивного сканирования я нахожу именно ваш результат в образце. Но это сомнительно: почему a*aaa aaa*aи нетab*c c*ab
edc65

Из-за правила 1. парсинга. Да, умножение обычно коммутативно, но мы не заходим так далеко - мы просто хотим «перестроить» умножение в том порядке, в котором оно было сделано. На самом деле в языке Джека мы могли бы иметь матричный тип - тогда умножение не является коммутативным. И «аааа» может быть как противопоставление «ааа» и «а», так и «а» и «ааа» - это не для коммутативности, скорее для неопределенности, которую мы принимаем во внимание как.
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.