Verwenden Sie den dritten Stapel
Wenn Sie den Titel gelesen haben, sind Sie möglicherweise etwas verwirrt. Sicher gibt es in Brain-Flak nur zwei Stapel? Ich versichere Ihnen jedoch, dass es existiert und eines der mächtigsten, wenn nicht das mächtigste Werkzeug beim Schreiben und Golfen von Brain-Flak ist.
Was ist der "Dritte Stapel"?
Jedes Brain-Flak-Programm verwendet den dritten Stapel auf die eine oder andere Weise, aber der Großteil der Verwendung geschieht hinter den Kulissen, und es ist oft nützlich, die Tatsache, dass er existiert, einfach zu ignorieren. Jede Klammer im Programm fügt entweder ein Element zum Stapel hinzu oder entfernt es. Drei der offenen Klammern ([<
fügen alle einen Gegenstand zum Stapel hinzu, während ihre drei Konjugate )]>
alle einen Gegenstand vom Stapel entfernen. Der Wert des Elements auf dem Stapel entspricht dem Wert des aktuellen Programmumfangs, und die Verwendung von Nullen ändert diesen Wert auf bestimmte Weise. Die enge Klammer )
hat die einzigartige Funktion, ein Element vom dritten Stapel in den aktuellen Stapel zu verschieben. ein Stoß.
Hoffentlich wird dir das klar. Der dritte Stapel ist eine Art Stapel, der sich die Rückgabewerte des bereits ausgeführten Codes merkt. Lassen Sie uns ein Beispiel eines einfachen Programms durchgehen, das die beiden normalen Stapel und den dritten Stapel verfolgt.
Beispiel
Wir werden das folgende Programm durchgehen. Dieses Programm schiebt -3, 1, -2
auf den Stapel.
(([()()()])(()))
Wir beginnen mit drei offenen Klammern, die alle eine Null auf den dritten Stapel schieben.
Unsere Stapel sehen jetzt so aus, der dritte Stapel ist der rechts und der aktive Stapel hat einen ^
darunter:
0
0
0 0 0
^
(([()()()])(()))
^
Jetzt haben wir drei ()
Niladen. Diese machen nichts mit den normalen zwei Stapeln, aber sie addieren jeweils einen oben auf dem dritten Stapel, so dass unsere Stapel wie folgt aussehen:
3
0
0 0 0
^
(([()()()])(()))
^
Jetzt stellen wir ]
fest, dass in geschweiften Klammern ein Element aus dem dritten Stapel entfernt wird. Es ]
hat jedoch die Funktion, das entfernte Element vom oberen Rand des Stapels zu subtrahieren. So sehen unsere neuen Stacks aus:
-3
0 0 0
^
(([()()()])(()))
^
Das macht Sinn; [...]
tut die Verneinung so ]
sollte nach unten subtrahieren.
Jetzt müssen wir eine ausführen )
. Wie Sie sich wahrscheinlich erinnern, )
ist dies die Stelle im Programm, an der die Daten auf den Stapel verschoben werden, sodass wir den oberen Teil des dritten Stapels auf den aktuellen Stapel verschieben. Außerdem werden wir -3
das Element zum nächsten Element im dritten Stapel hinzufügen .
-3 0 -3
^
(([()()()])(()))
^
Wieder treffen wir auf eine unserer drei offenen Klammern, damit wir unserem dritten Stapel ein weiteres Element hinzufügen können.
0
-3 0 -3
^
(([()()()])(()))
^
Wie bereits erwähnt, ()
wird der obere Teil unseres dritten Stapels um eins erhöht.
1
-3 0 -3
^
(([()()()])(()))
^
Und )
verschiebt den oberen Rand des dritten Stapels auf den aktiven Stapel und addiert ihn nach unten
1
-3 0 -2
^
(([()()()])(()))
^
Der letzte )
verschiebt den dritten Stapel auf den aktiven Stapel, und da auf dem dritten Stapel keine Elemente mehr zum Hinzufügen vorhanden sind, geschieht nichts anderes.
-2
1
-3 0
^
(([()()()])(()))
^
Das Programm ist beendet und wir beenden es und geben es aus.
Dieses Beispiel soll Ihnen ein Gefühl dafür vermitteln, was der dritte Stapel ist und tut. Es enthält nicht alle Operationen, aber hoffentlich können Sie herausfinden, was jede für sich tut. Wenn Sie immer noch Probleme haben, habe ich ein "Spickzettel" am Ende dieser Antwort beigefügt, um Ihnen weiterzuhelfen.
In Ordnung und jetzt?
Ok, jetzt verstehst du den dritten Stapel, aber "Na und"? Sie haben es bereits verwendet, auch wenn Sie es nicht als "Third Stack" bezeichnet haben. Wie hilft Ihnen das Denken in Bezug auf den Third Stack beim Golfen?
Schauen wir uns ein Problem an. Sie möchten das Dreieck einer Zahl nehmen . Dies ist die Summe aller Zahlen kleiner als n.
Ein Ansatz könnte darin bestehen, einen Akkumulator im Offstack zu erstellen und diesen beim Herunterzählen hinzuzufügen. Dies erzeugt Code, der so aussieht:
(<>)<>{(({}[()])()<>{})<>}{}<>({}<>)
Probieren Sie es online!
Dieser Code ist ziemlich kompakt und man könnte meinen, dass er nicht viel kleiner werden kann. Wenn wir es jedoch von einem dritten Stapel aus betrachten, wird klar, dass dies grob ineffizient ist. Anstatt unseren Akku in den Stapel zu legen, können wir ihn mit einem auf den dritten Stapel legen (
und ihn am Ende unseres Gebrauchs abrufen )
. Wir werden noch einmal alle Zahlen durchlaufen, aber dieses Mal müssen wir nicht viel tun, um unseren dritten Stapel zu erhöhen, das Programm erledigt das für uns. Das sieht so aus:
({()({}[()])}{})
Probieren Sie es online
Dieser Code ist weniger als halb so groß wie die ziemlich gut golfene Version, die wir zuvor gemacht haben. Tatsächlich hat eine Computersuche bewiesen, dass dieses Programm das kürzestmögliche Programm ist, das diese Aufgabe ausführen kann. Dieses Programm kann mit dem Ansatz "Summe aller Läufe" erklärt werden, aber ich denke, es ist viel intuitiver und klarer, wenn es mit einem Third-Stack-Ansatz erklärt wird.
Wann verwende ich den dritten Stapel?
Wenn Sie mit der Arbeit an einem neuen Problem in Brain-Flak beginnen, sollten Sie sich im Idealfall überlegen, wie ich dies mit Blick auf den dritten Stapel tun würde. Als Faustregel gilt jedoch, dass Sie immer dann, wenn Sie eine Art Akkumulator oder eine laufende Summe im Auge behalten müssen, versuchen sollten, diesen auf Ihren dritten Stapel zu legen, anstatt auf die beiden echten Stapel.
Eine andere Möglichkeit, über die Verwendung Ihres dritten Stapels nachzudenken, besteht darin, dass Sie auf den beiden anderen Stapeln keinen Platz zum Speichern von Werten haben. Dies kann besonders nützlich sein, wenn Sie an zwei vorhandenen Stapeln Änderungen vornehmen und einen Wert für die spätere Verwendung speichern möchten, ohne den Überblick zu behalten, wo er sich befindet.
Einschränkungen des dritten Stapels
Der dritte Stapel ist in vielerlei Hinsicht sehr leistungsfähig, hat jedoch seine eigenen Einschränkungen und Nachteile.
Zunächst wird die maximale Stapelhöhe für den dritten Stapel zu einem bestimmten Zeitpunkt zur Kompilierungszeit festgelegt. Dies bedeutet, dass Sie, wenn Sie eine Menge Speicherplatz auf dem Stapel verwenden möchten, diesen Speicherplatz beim Schreiben des Programms zuweisen müssen.
Zweitens ist der dritte Stapel kein wahlfreier Zugriff. Dies bedeutet, dass Sie keine Operationen mit einem Wert ausführen können, der nicht der höchste Wert ist. Außerdem können Sie keine Werte auf dem Stapel verschieben (z. B. die ersten beiden Elemente austauschen).
Fazit
Der dritte Stapel ist ein mächtiges Werkzeug und ich würde es für jeden Brain-Flak-Benutzer als wesentlich erachten. Es ist gewöhnungsbedürftig und erfordert ein Umdenken in Bezug auf das Programmieren in Brain-Flak, aber bei richtiger Anwendung macht es den Unterschied zwischen einem anständigen und einem erstaunlichen Golfspiel.
Spickzettel
Hier finden Sie eine Liste der Vorgänge und deren Auswirkungen auf den dritten Stapel
Operation | Action
====================================================
(,[,< | Put a zero on top of the Third Stack
----------------------------------------------------
) | Add the top of the Third Stack to the
| second element and move it to the
| active stack
----------------------------------------------------
] | Subtract the top of the Third Stack
| from the second element and pop it
----------------------------------------------------
> | Pop the top of the Third Stack
----------------------------------------------------
() | Add one to the top of the Third Stack
----------------------------------------------------
{} | Pop the top of the active stack and
| add it to the top of the Third Stack
----------------------------------------------------
[] | Add the stack height to the Third
| Stack
----------------------------------------------------
<>,{,} | Nothing