Quylthulg ist eine Sprache von Chris Pressey, die versucht, das Problem der Infix-Notation mit dem zu lösen, was sie panfix nennt :
Ähnlich wie bei Postfix erfordert Panfix nicht die Bereitstellung geheimer Funktionen wie Klammern, um die Standardpriorität eines Operators zu überschreiben. Gleichzeitig ermöglicht panfix die Angabe von Begriffen in der gleichen Reihenfolge und Weise wie bei infix, was für diejenigen, die sich daran gewöhnt haben, eine zweifellos natürliche und intuitive Notation ist.
Wie erhalten Sie die Bequemlichkeit der Infixnotation zusammen mit der Eindeutigkeit von Präfix oder Postfix? Verwenden Sie natürlich alle drei!
=y=+*3*x*+1+=
Seien Sie formal gesehen +
ein Operator a
und b
Ausdrücke. (a+b)
Ist dann ein gültiger (in Klammern stehender) Infix-Ausdruck, ist die panfix-Darstellung dieses Ausdrucks +a+b+
, wobei Nebeneinanderstellung Verkettung darstellt.
Ihr Ziel ist es, einen Panfix-String zu nehmen und in ein Infix in Klammern umzuwandeln:
(y=((3*x)+1))
Der Einfachheit halber nehmen wir die folgenden Änderungen vor:
- Operatoren können nur aus zwei eindeutigen Zeichen bestehen (Sie können ein beliebiges Zeichen auswählen, aber hier verwende ich
*
und+
). - Es gibt nur ein Literal, das aus einem anderen eindeutigen Zeichen besteht (Sie können ein beliebiges auswählen, aber hier werde ich es verwenden
_
). - Die Eingabe ist ein wohlgeformter Panfix-Ausdruck.
Aus Gründen der Komplexität nehmen wir die folgenden Änderungen vor:
- Operatoren können aus einer beliebigen positiven Anzahl von Zeichen bestehen, nicht nur aus einem.
Dies macht die Herausforderung schwieriger, da Sie nicht unbedingt bestimmen können, wie eine bestimmte Teilzeichenfolge von Operatorzeichen partitioniert ist, ohne den Rest der Zeichenfolge zu betrachten.
Hier ist eine Referenzimplementierung für die Herausforderung mit freundlicher Genehmigung von @ user202729.
Testfälle
format: input -> output
+*+_*+_*+++_+*+_*+_*+++ -> ((_*+_)+(_+(_*+_)))
**++*+***++_+_++_+*++*+***_*++*+*****_**_*_*** -> ((((_+_)+_)*++*+***_)*(_*(_*_)))
***_**_***_* -> ((_**_)*_)
+_+_+ -> (_+_)
*+*+++**+***+++++_*+*+++**+***+++++_*+*+++**+***+++++ -> (_*+*+++**+***+++++_)
*++++*+*_*_*+*+++****+_++****+_++****++*+*+++_*+++ -> (((_*_)+*+(_++****+_))*+++_)
+**+_*+_*+*_*+*_*+*_+*_+**+ -> (((_*+_)*_)+(_*(_+*_)))
+**+++++_+++++_+++++*_*+*+_++++++_+++++_+++++++* -> (((_+++++_)*_)+*(_+(_+++++_)))
+*+*+_+*+_+*+*_*+*_*+*+_+*+_+*+*+ -> (((_+*+_)*_)+(_*(_+*+_)))
**_**_**_*_****_* -> ((_*(_*(_*_)))*_)
Ich habe dieses Programm verwendet , um Infix-Strings für diese Herausforderung zu generieren (das Konvertieren in Panfix war trivial, das Umkehren jedoch nicht).
**_**_**_*_****_*
. Die Antworten, die ich getestet habe, sind alle fehlgeschlagen.(_ + _)
.Antworten:
Prolog (SWI) ,
194163 BytesHat mit diesem Tipp satte 31 Bytes von 0 ' gespeichert !
Der Operator verwendet als
^
linkes Argument einen String mit einem Panfix-Ausdruck und setzt sein rechtes Argument auf einen String mit dem entsprechenden Infix-Ausdruck in Klammern. Es wirdx
als Literal anstelle von verwendet_
.Probieren Sie es online!
Erläuterung
Da Prolog eine deklarative Sprache ist, müssen wir nur die Beziehung zwischen einem panfix und einem Ausdruck in Klammern beschreiben.
Die Erklärung verwendet diese leicht ungolfed Version:
Unsere Hauptproduktion ist
parenthesize
, einen panfix-AusdruckX
als String aufzunehmen und den entsprechenden Infix-Ausdruck in KlammernP
als String auszusenden . Es verwendetstring_chars
die Eingabezeichenfolge in eine Liste von Zeichen zu konvertieren und dann geht es einfach aufexpr
.expr
L
Nimmt eine Liste von Zeichen auf , analysiert den ersten Panfix-Ausdruck, den es findetL
, und sendet das in Klammern gesetzte ÄquivalentX
und den Rest der Liste von ZeichenR
. Es gibt zwei mögliche Arten von Ausdrücken:L
istx
, dann ist der Ausdruckx
und der Rest ist alles nach demx
.O
(sieheoper
unten). einen Ausdruck analysierenY
;O
erneut analysieren ; einen anderen Ausdruck analysierenZ
; undO
ein drittes Mal analysieren . Der Rest ist alles nach der dritten Instanz vonO
. Der Ausdruck ist das Ergebnis der VerbindungY
,O
undZ
durch Klammern umgeben, in einen String.oper
nimmt eine Liste von Zeichen auf, wobei das erste ZeichenC
und der Rest sindT
; Es analysiert einen Operator (dh eine Folge von einem oder mehreren Operator-Zeichen) und sendet den OperatorO
und den Rest der Liste der ZeichenR
. Um einen Operator zu bilden,C
muss das Zeichen etwas anderes sein alsx
; auch nichtP
muss für denT
Rest syntaktisch analysierbar seinR
. in diesem FallO
ist die Verkettung vonC
undP
; oder,O
ist das einzelne ZeichenC
; In diesem FallR
ist es einfachT
.Ein gelungenes Beispiel
Nehmen wir die Eingabe
+*+x+x++*x+*
als Beispiel.+*+x+x++*x+*
. Das fängt nicht damit anx
, also analysieren wir einen Operator von Anfang an.oper
wird einen Operator so groß wie möglich analysieren, also versuchen wir es+*+
.x+x++*x+*
. Das muss seinx
.+*+
, von+x++*x+*
. Dies schlägt jedoch fehl .+*
stattdessen, den Operator zu analysieren .+x+x++*x+*
. Das fängt nicht damit anx
, also müssen wir einen Operator analysieren.+
.x+x++*x+*
. Das muss seinx
.+
nochmal parsen ab+x++*x+*
.x++*x+*
. Das muss seinx
.+
nochmal parsen ab++*x+*
.(x+x)
.+*
erneut von+*x+*
.x+*
. Das muss seinx
.+*
nochmal parsen ab+*
.((x+x)+*x)
.Da keine Zeichen mehr übrig sind, haben wir den Ausdruck erfolgreich übersetzt.
quelle
Perl,
7860585750 BytesEnthält
+1
fürp
Verwendet
1
für+
und2
für*
(oder tatsächlich funktioniert jede Ziffer für jeden Operator)Zum bequemen Testen im Vergleich zu den angegebenen Beispielen können Sie diese verwenden, die die Übersetzungen und das Entfernen von Leerzeichen für Sie erledigt:
quelle
Sauber ,
200192189 BytesProbieren Sie es online!
Definiert die Funktion
f
, nimmtString
einen Singleton und gibt ihn[String]
mit dem Ergebnis zurück.Einige nette Sachen:
_
quelle
Retina 0.8.2 , 138 Bytes
Probieren Sie es online! Link enthält die schnelleren Testfälle. Erläuterung: Die Regex-Steuerkomponente verwendet die Rückverfolgung, um die Zeichenfolge in Token aufzuteilen, die dann in den
i
Bilanzkreis verschoben oder aus diesem entfernt werden . Es wird immer mindestens ein Operator ausgeführt, der am Anfang vor die erste Variable gedrückt wird. Nach einer Variablen wird mindestens ein Operator eingefügt. Zu diesem Zeitpunkt ist entweder ein Push-Operator-Lauf oder eine andere Variable zulässig. Operatoren werden doppelt an die Gruppe weitergeleitet, damit sie korrekt abgerufen werden können. Beispiel:Leider hilft uns dies nicht, die Ergebnisse zu erfassen, um sie in Klammern zu setzen, sodass der äußere Operator manuell abgeglichen wird. Die Klammern werden von außen nach innen hinzugefügt. In der ersten Stufe wird der gesamte Ausdruck in Klammern eingeschlossen, und in der letzten Stufe werden sie entfernt, nachdem sie auf die Variablen übertragen wurden.
quelle
**_**_**_*_****_*
.Haskell ,
167166 BytesProbieren Sie es online! Anwendungsbeispiel:
head.e "**_**_**_*_****_*"
Erträge((_*(_*(_*_)))*_)
. Alle Zeichen außer_
werden als Operatoren interpretiert,_
selbst bezeichnet eine Kennung.quelle
Python 3, 226 Bytes
Definiert eine anonyme Funktion mit dem Namen
R
.Probieren Sie es online!
quelle
_*+
. das war genau das, was im Beispiel verwendet wurde. Sie können dies möglicherweise verwenden, um Ihre regulären Ausdrücke zu spielen (z. B. indem Sie\d
anstelle von verwenden[*+]
).