Präfixnotation zur Postfixnotation

19

Haftungsausschluss: Nein, dies ist keine Scherzaufforderung, um eine Zeichenfolge umzukehren.

Aufgabe

Es gibt nur eine zu unterstützende Operation: subtraction ( -).

Sie müssen auch nur zwei Atome unterstützen: null ( 0) und eins ( 1).

Hier entspricht die Präfixnotation -ABder Postfixnotation AB-, wobei Aund BAusdrücke sind.

Ihre Aufgabe ist es, einen Ausdruck in Präfixnotation (rekursiv) in den entsprechenden Ausdruck in Postfixnotation umzuwandeln.

Definitionen

Ein Ausdruck in Präfixnotation wird von der folgenden Grammatik generiert:

S > -SS
S > 0
S > 1

Ein Ausdruck in Postfix-Notation wird von der folgenden Grammatik generiert:

S > SS-
S > 0
S > 1

Beispiel

Prefix notation:  --01-0-01
Parentheses:      -(-01)(-0(-01))
Convert:          (01-)(0(01-)-)-
Postfix notation: 01-001---

Regeln und Freiheit

  • Sie können die Operation und die Atome in ein beliebiges Zeichen umbenennen, sofern dies konsistent ist.
  • Das Eingabeformat muss mit dem Ausgabeformat übereinstimmen (abgesehen von der Tatsache, dass die Eingabe in Präfixnotation und die Ausgabe in Postfixnotation erfolgt).

Testfall

Input       Output
1           1
0           0
-01         01-
-10         10-
--01-0-01   01-001---

Testet Credits für Dada .

Undichte Nonne
quelle
1
Können Sie bitte noch ein paar Testfälle hinzufügen?
Shaggy
@Shaggy, welche Art von Testfällen möchten Sie?
Undichte Nonne
@LeakyNun Ist es in Ordnung, die Eingabe und Ausgabe als Iteratoren zu verwenden, wie ich es in der neuesten Version meiner Antwort getan habe?
L3viathan
@ L3viathan Ich nehme an ...
Undichte Nonne

Antworten:

12

Brainfuck , 32 Bytes

,[[->++++<<+>]>[[-]<<[.[-]<]]>,]

Probieren Sie es online!

Ich habe @als Operation verwendet, weil der Codepunkt (64) praktisch ist. Uist auch bei gleicher Byteanzahl mit 3 * 85 + 1 = 256 = 0 möglich.

Erläuterung

Das Band wird als Stapel verwendet. In jeder Iteration der Hauptschleife startet der Datenzeiger zwei Zellen rechts oben im Stapel.

,[                Take input and start main loop
  [->++++<<+>]    Push input, and compute 4*input
  >[              If 4*input is nonzero (and thus input is not @):
    [-]<<           Zero out this cell and move to top of stack
    [.[-]<]         Pop from stack and output until \0 is reached
  ]
  >,              Move pointer into the correct position.  If input was @, the earlier > pushed \0 onto the stack.
]
Nitrodon
quelle
6

Retina , 37 30 29 Bytes

M!`-*.
+m`^-(.*)¶(\d.*)
$1$2-

Probieren Sie es online! Durch die Erkenntnis, dass Begriffe immer mit einer Ziffer beginnen, wurden 7 Bytes eingespart, sodass ich die Übereinstimmung -nicht mehr auf die letzte Stelle beschränken muss (zuvor war dies die einzige Stelle, auf die garantiert zwei Begriffe folgen). 1 Byte gespart, indem -s nicht in die eigene Zeile gesetzt wird. Zum Beispiel -01wird -0¶1das dann durch ersetzt 01-. Nun, wenn ich --010also --0¶1¶0dann will ich den inneren zu ändern , -0¶1um 01-so , dass ich die ersetzen kann -01-¶0mit 01-0-, aber es funktioniert nicht wirklich unabhängig davon , welche der beiden -s ich entfernen, so dass ich die man am Anfang der Zeile entfernen, wie Das ist einfacher zu testen.

Neil
quelle
Ich denke, das ist dein Etwas :)
Leo
@Leo Funktioniert generell nicht, -0-0-00sollte zB werden 0000---.
Neil
Du hast recht, sorry. Ich habe eine andere Idee, aber sie ist wesentlich anders. Deshalb werde ich sie als neue Antwort veröffentlichen
Leo,
1
@Leo Ich habe jetzt etwas gefunden ...
Neil
1
@Leo Mit meinem letzten Golf sind wir gebunden!
Neil
6

Haskell , 62 59 Bytes

f(x:r)|x>'-'=([x],r)|(a,(b,c))<-f<$>f r=(a++b++"-",c)
fst.f

Probieren Sie es online! Verbrauch: fst.f $ "--01-0-01". 0und 1können beliebige Zeichen sein, die größer als das Zeichen sind -.

Edit: -3 Bytes dank Zgarb!

Die Funktion fanalysiert rekursiv einen Ausdruck und gibt ein Tupel dieses Ausdrucks in Postfix-Notation und die Restzeichenfolge zurück. Dabei wird der einfachen Grammatik gefolgt, aus der gültige Präfix-Ausdrücke erstellt werden können:

<exp> ::= - <exp> <exp> | 0 | 1

Wenn das erste Zeichen ader Eingabezeichenfolge größer als ist -, befinden wir uns an einem atomaren Ausdruck und geben ein Tupel einer Zeichenfolge mit dem Zeichen aund dem Rest der Eingabezeichenfolge zurück.

Wenn wir einen finden - , müssen zwei Ausdrücke analysiert werden. Dies kann erreicht werden, indem (a,x)<-f rder erste Ausdruck aabgerufen und dann die Restzeichenfolge xerneut analysiert wird (b,c)<-f x, um den zweiten Ausdruck bund die endgültige Restzeichenfolge abzurufen c. (a,(b,c))<-f<$>f rTut genau das, weil <$>bei Tupeln eine Funktion zwei das zweite Element eines Tupels abbildet und dabei drei Bytes kürzer ist als (a,x)<-f r,(b,c)<-f x. Nachdem beide Ausdrücke und den Rest - String zu erhalten, werden die Ausdrücke verkettet und ein „-“ angefügt: (a++b++"-",c).

Laikoni
quelle
1
Sie können 3 Bytes sparen, indem Sie die Fälle kombinieren:f(x:r)|x>'-'=([x],r)|(a,(b,c))<-f<$>f r=(a++b++"-",c)
Zgarb
@ Zgarb Danke! Aus irgendeinem Grund habe ich nur darüber nachgedacht, f(x:r)|x<'0',(a,(b,c))<-f<$>f r=(a++b++"-",c)|1<3=([x],r)als ich nach einer Version mit beiden Fällen zusammen gesucht habe, die Byte länger ist.
Laikoni
5

Haskell, 54 Bytes

v f""=""
v f(a:s)=last(v.v:[id|a>'-'])((a:).f)s
h=v h

Die Funktion vübernimmt eine Zeichenfolge und eine Funktion, ordnet den anfänglichen Unterausdruck neu an und wendet die Funktion dann auf den Rest der Zeichenfolge an, bis alles neu angeordnet wurde. Der Aufrufstapel und das Funktionsargument verfolgen zusammen, welcher Ausdruck analysiert wird. Die Funktion hbeantwortet die Herausforderung und ist gerechtv als erstes Dummy-Argument mit sich selbst aufgerufen.

faubi
quelle
1
Wow! (1) Das sind nur 53, Sie müssen den letzten Zeilenumbruch nicht zählen. (2) Die erste Zeile kann auf gekürzt werden, v f l=lwenn Sie sie an zweiter Stelle verschieben.
Ørjan Johansen
1
Ich glaube nicht, dass Sie mehr als einen ganzen Ausdruck analysieren müssen, damit Sie ein Byte mit der anonymen Funktion speichern können v id.
Ørjan Johansen
1
Tatsächlich wird die erste Zeile bei einer gültigen Eingabe nie aufgerufen, sodass Sie sie einfach löschen können.
Ørjan Johansen
1
Die Aufteilung in Wachen scheint den lastTrick um ein Byte zu übertreffen .
Ørjan Johansen
4

Perl 5 , 57 Bytes

sub f{"@_"=~s/x((?0)|.)((?0)|.)/my$n=$2;f($1).f($n).x/re}

Ich benutze xals Operator statt -(siehe den TryItOnline-Link unten).

Probieren Sie es online!

Erklärungen:
/x((?0)|.)((?0)|.)/ Stimmt rekursiv mit einem vollständigen Ausdruck überein: a xam Anfang, dann ein Ausdruck (?0)(es ist ein rekursiver Aufruf) oder ein Atom ( .), gefolgt von einem anderen Ausdruck oder Atom.
Dann muss ich den zweiten Ausdruck / atom ( my$n=$2;) speichern, da er sonst von den rekursiven Aufrufen überschrieben wird.
Die Funktion wird dann rekursiv auf den ersten Ausdruck ( f($1)), dann auf den zweiten f($n)und xam Ende ( .x) angehängt .

Dada
quelle
4

Python 3, 117 112 105 100 98 76 62 61 59 Bytes

def p(s):x=next(s);yield from[x]*(x>"-")or[*p(s),*p(s),"-"]

Änderungsprotokoll:

  • entfernte Zeilenumbrüche wo möglich (-5 Bytes)
  • Lambda anstelle einer vollen Funktion (-7 Bytes, danke @Dada)
  • nein sonst (-5 bytes, danke @Leaky Nun)
  • rückgängig machen übereifriges Golfen (-2 Bytes, danke @Leaky Nun)
  • arbeite stattdessen an einer globalen Liste (-22 Bytes)
  • eigentlich arbeiten wir stattdessen an Iteratoren (-14 Bytes)
  • ändere !=auf >(-1 Byte, kopiert von @ovs Vorschlag)
  • Lazy Evaluation Trickery (-2 Bytes, danke @ovs)

Benutze es so:

>>> list(p(iter("--01-0-01")))
['0', '1', '-', '0', '0', '1', '-', '-', '-']
L3viathan
quelle
2
lambda x:p(x)[0]könnte wohl deine ffunktion ersetzen .
Dada
1
Das brauchst du nicht else.
Undichte Nonne
1
Spart d="-"Bytes wirklich?
Undichte Nonne
1
def p(s):x=next(s);yield from[x]*(x>"-")or[*p(s),*p(s),"-"]für 59 Bytes
Ovs
3

Pyth, 20 Bytes

L+&-hbTsyM.-Btbytbhb

Dies schafft eine Funktion y , die eine Zeichenfolge als Parameter erwartet.

Probieren Sie es online aus: Demonstration oder Test Suite

Erläuterung:

Die Funktion yanalysiert und konvertiert den ersten Präfix-Ausdruck in einen Postfix-Ausdruck. Wenn es also so heißt y"10", wird es nur zurückkehren 1.

L+&-hbTsyM.-Btbytbhb
L                      define a function y(b), that returns:
   -hbT                   remove the chars "10" from the first char b
                          (T=10, and - will convert a number to a string)
  &                       if this gives the empty string (a falsy value)
 +                hb         then append b[0] to it and return it
                             (so this will parse a digit 0 or 1 from the string)
  &                       otherwise (the first char is a -)
               ytb           parse the first prefix expression from b[1:]
                             (recursive call)
          .-Btb              remove this parsed expression bifurcated from b[1:]
                             this gives a tuple [b[1:], b[1:] without first expr]
        yM                   parse and convert an expression from each one
       s                     join the results
 +                hb         and append the b[0] (the minus) to it and return
Jakube
quelle
2

Retina , 34 31 29 Bytes


;
-;
¶
+`¶(.+);(.+)
$1$2-
;

Probieren Sie es online!

;werden verwendet, um Knoten anzugeben, die anfänglich aus einer einzelnen Zahl bestehen und dann zu allem wachsen, was bereits analysiert wurde. -werden in Zeilenumbrüche umgewandelt, damit .+wir alles erfassen können, was nicht ungeparst ist -.

Löwe
quelle