IMP: Impliziter Multiplikationsparser

9

Jack mag die Programmiersprache C, hasst es aber, Ausdrücke zu schreiben V=a*b*h; , um die Werte zu multiplizieren.

Er möchte V=abh;stattdessen schreiben , warum sollte der Compiler darüber stöhnen, dass das abhSymbol undefiniert ist, da int a, b, h;es definiert ist, damit wir die Multiplikation ableiten können?

Helfen Sie ihm, einen Parser zu implementieren, der einen einzelnen Multiplikationsterm entschlüsselt, sofern die im aktuellen Bereich definierten Variablen bekannt sind.

Der Einfachheit halber wird das Multiplizieren mit der Zahl (wie in 2*a*b) nicht berücksichtigt, es werden nur Variablen angezeigt.

Die Eingabe ist ein Multiplikationsterm T , der den regulären Ausdruck erfüllt:

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

und eine variable Menge Z .

Eine Analyse P des Terms T über die Variablensatz Z ist eine Zeichenfolge, die Folgendes erfüllt:

  1. Nachdem *wir alle Vorkommen von P entfernt haben, erhalten wir T,
  2. entweder ist ein Variablenname von Z oder besteht aus richtigen Variablennamen von Z, die durch einzelne *Zeichen aufgeteilt sind.

Die Lösung sollte alle Analysen eines Begriffs drucken.

Stichprobe:

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

Die Eingabe (die Liste der Variablen und der Begriff) kann auf jede für die Sprache geeignete Weise bereitgestellt werden.

Die Ausgabe kann in jeder sinnvollen Form erfolgen (eine Analyse pro Zeile oder eine durch Kommas getrennte Liste usw.) - sie sollte jedoch eindeutig und lesbar sein.

Eine leere Ausgabe ist akzeptabel, wenn ein Begriff nicht analysiert werden kann (in den Beispielen habe ich der Übersichtlichkeit halber '-' verwendet).

Dies ist ein Code Golf, also gewinnt der kürzeste Code.

pawel.boczarski
quelle
1
In Ihrem ersten Beispiel glaube ich, dass ab*ces sich um eine falsche Analyse handelt, da dies ckeine zulässige Variable ist.
isaacg
1
Bei einem rekursiven Scan finde ich genau Ihr Ergebnis in der Probe. Aber es ist fraglich: warum a*aaa aaa*aund nichtab*c c*ab
edc65
Wegen Regel 1. des Parsens. Ja, Multiplikation ist normalerweise kommutativ, aber wir gehen nicht so weit - wir wollen die Multiplikation nur in der Reihenfolge "rekonstruieren", in der sie durchgeführt wurde. Tatsächlich könnten wir in Jacks Sprache einen Matrixtyp haben - die Multiplikation ist dann nicht kommutativ. Und "aaaa" kann sowohl ein Nebeneinander von "aaa" als auch "a" oder "a" und "aaa" sein - dies nicht aus Gründen der Kommutativität, sondern aus Gründen der Mehrdeutigkeit, die wir beide berücksichtigen.
pawel.boczarski
Exaktes Duplikat von codegolf.stackexchange.com/questions/45496/…
Feersum

Antworten:

4

Pyth, 18 Zeichen

mj\*dfqzsTsm^Qkhlz

Diese Lösung wurde aus meiner Interpreting Fish- Lösung übernommen. Die Probleme sind eigentlich sehr ähnlich.

Erwartet Eingabe als solche:

aaaa
"a", "aaa"

Gibt Ausgabe wie folgt:

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

Probieren Sie es hier aus.

  • sm^Qkhlz: Erzeugt alle Folgen von Variablen, die bis zur Länge der Eingabezeichenfolge die Anzahl der Variablen enthalten.

  • fqzsT: Filtert die variablen Sequenzen heraus, die mit der Eingabezeichenfolge übereinstimmen

  • mj\*d: Fügt das *Symbol ein und druckt.

isaacg
quelle
3

Python 2 - 147 94 Bytes


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))

Dies definiert eine Funktion R, die wie folgt verwendet werden soll:

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

Druckt die Ausgabe wie folgt:

a*bc
ab*c
matsjoyce
quelle
1

JavaScript (ES6) 111

Angepasst an meine "Fisch" -Antwort besteht der Hauptunterschied darin, alle Lösungen zu finden, nicht nur die erste.

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,[])

Die Ausgabe wird auf der Konsole gedruckt. Das Funktionsergebnis hat keine Bedeutung und muss verworfen werden.

Test In Firefox / Firebug - Konsole

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
edc65
quelle