Użyj trzeciego stosu
Jeśli przeczytałeś tytuł, możesz być nieco zdezorientowany. Z pewnością w Brain-Flak są tylko dwa stosy? Zapewniam cię jednak, że istnieje i jest jednym z najpotężniejszych, jeśli nie najpotężniejszym narzędziem do pisania i gry w golfa Brain-Flak.
Co to jest „trzeci stos”?
Każdy program Brain-Flak korzysta z trzeciego stosu w taki czy inny sposób, ale większość zastosowań odbywa się za kulisami i często przydatne jest po prostu zignorowanie faktu, że on istnieje. Każdy nawias w programie albo dodaje lub usuwa jeden element ze stosu. Trzy otwarte nawiasy klamrowe ([<
dodają przedmiot do stosu, a )]>
wszystkie trzy sprzężone usuwają przedmiot ze stosu. Wartość elementu na stosie jest wartością bieżącego zakresu programu i użycie niladów zmodyfikuje tę wartość w określony sposób. Nawias zamknięty )
ma unikalną funkcję przenoszenia elementu z trzeciego stosu na bieżący stos; pchniecie.
Mam nadzieję, że stanie się to dla ciebie jasne. Trzeci stos to rodzaj stosu, który zapamiętuje zwrócone wartości kodu, który został już wykonany. Przejdźmy przez przykład prostego programu śledzącego dwa normalne stosy i trzeci stos.
Przykład
Przejdziemy przez następujący program. Ten program wypycha -3, 1, -2
na stos.
(([()()()])(()))
Zaczynamy od trzech otwartych nawiasów klamrowych, z których wszystkie przesuwają zero na trzeci stos.
Nasze stosy wyglądają teraz tak, trzeci stos jest tym po prawej, a aktywny stos ma ^
pod spodem:
0
0
0 0 0
^
(([()()()])(()))
^
Teraz mamy trzy ()
nilady. Nie powodują one żadnych zmian w stosunku do dwóch normalnych stosów, jednak każdy z nich dodaje jeden do góry trzeciego stosu, dzięki czemu nasze stosy wyglądają następująco:
3
0
0 0 0
^
(([()()()])(()))
^
Teraz napotykamy, ]
jak stwierdzono, zanim zamknięte nawiasy klamrowe usuwają element z Trzeciego Stosu, ale ]
mają funkcję odejmowania elementu, który usuwa z wierzchu stosu. Tak więc nasze nowe stosy będą wyglądały następująco:
-3
0 0 0
^
(([()()()])(()))
^
To ma sens; [...]
robi negację, więc ]
należy odjąć w dół.
Teraz musimy wykonać )
. Jak zapewne pamiętacie, )
miejsce w programie, w którym rzeczy są wypychane na stos, więc będziemy przenosić górę Trzeciego Stosu na bieżący stos, dodatkowo dodamy -3
następny element na trzecim stosie.
-3 0 -3
^
(([()()()])(()))
^
Ponownie napotykamy jeden z naszych trzech otwartych nawiasów klamrowych, więc dodamy kolejny element do naszego Trzeciego Stosu.
0
-3 0 -3
^
(([()()()])(()))
^
Jak powiedzieliśmy wcześniej ()
, zwiększy górną część naszego trzeciego stosu o jeden.
1
-3 0 -3
^
(([()()()])(()))
^
I )
przeniesie górę trzeciego stosu na aktywny stos i doda w dół
1
-3 0 -2
^
(([()()()])(()))
^
Ostatni )
przenosi trzeci stos na aktywny stos, a ponieważ na trzecim stosie nie ma już żadnych elementów do dodania, nie robi nic więcej.
-2
1
-3 0
^
(([()()()])(()))
^
Program się zakończył, więc kończymy i wysyłamy.
Ten przykład ma na celu dać ci wyobrażenie o tym, czym jest i co robi trzeci stos. Nie obejmuje wszystkich operacji, ale mam nadzieję, że możesz dowiedzieć się, co każda z nich robi sama. Jeśli nadal masz problemy, zamieściłem „ściągawkę” na dole tej odpowiedzi, aby Ci pomóc.
Ok, i co?
Ok, teraz rozumiesz trzeci stos, ale „co z tego”? Już go używałeś, nawet jeśli nie nazwałeś go „trzecim stosem”. W jaki sposób myślenie w kategoriach trzeciego stacka pomaga ci grać w golfa?
Spójrzmy na problem. Chcesz wziąć Trójkąt liczby . Jest to suma wszystkich liczb mniejszych niż n.
Jednym z podejść może być utworzenie akumulatora na offstacku i dodawanie go podczas odliczania. To tworzy kod, który wygląda następująco:
(<>)<>{(({}[()])()<>{})<>}{}<>({}<>)
Wypróbuj online!
Ten kod jest dość kompaktowy i można by pomyśleć, że nie może być znacznie mniejszy. Jeśli jednak podchodzimy do niego z punktu widzenia trzeciego stosu, staje się jasne, że jest to rażąco nieefektywne. Zamiast kłaść nasz akumulator na stosie, możemy umieścić go na trzecim stosie za pomocą (
i pobrać na końcu, którego używamy )
. Ponownie przejdziemy przez wszystkie liczby, ale tym razem nie musimy nic robić, aby zwiększyć nasz Trzeci Stos, program robi to za nas. To wygląda jak:
({()({}[()])}{})
Wypróbuj online
Ten kod jest mniej niż o połowę mniejszy od poprzedniej wersji gry w golfa. W rzeczywistości wyszukiwanie komputerowe wykazało, że ten program jest najkrótszym możliwym programem, który może wykonać to zadanie. Ten program można wyjaśnić za pomocą podejścia „suma wszystkich przebiegów”, ale myślę, że jest o wiele bardziej intuicyjny i przejrzysty, gdy wyjaśniono go przy użyciu podejścia trzeciego stosu.
Kiedy używam trzeciego stosu?
Idealnie, ilekroć zaczynasz pracę nad nowym problemem w Brain-Flak, powinieneś pomyśleć, jak bym to zrobił z myślą o trzecim stosie. Jednak jako ogólna zasada, ilekroć musisz śledzić jakiś rodzaj akumulatora lub mieć bieżącą sumę, dobrym pomysłem jest umieszczenie go na trzecim stosie zamiast dwóch prawdziwych stosów.
Innym razem dobrym pomysłem może być rozważenie użycia trzeciego stosu, gdy nie masz miejsca na przechowywanie wartości na dwóch pozostałych stosach. Może to być szczególnie przydatne, gdy wykonujesz manipulacje na dwóch istniejących stosach i chcesz zapisać wartość do późniejszego wykorzystania bez konieczności śledzenia jej położenia.
Ograniczenia trzeciego stosu
Trzeci stos jest bardzo mocny na wiele sposobów, ale ma swoje ograniczenia i wady.
Po pierwsze, maksymalna wysokość stosu dla trzeciego stosu w dowolnym punkcie jest określana w czasie kompilacji. Oznacza to, że jeśli chcesz użyć miejsca na stosie, musisz przydzielić to miejsce podczas pisania programu.
Po drugie, trzeci stos nie jest dostępem losowym. Oznacza to, że nie można wykonywać żadnych operacji na żadnej wartości poza najwyższą wartością. Ponadto nie możesz przenosić wartości na stosie (powiedz zamień pierwsze dwa elementy).
Wniosek
Trzeci stos to potężne narzędzie, które uważam za niezbędne dla każdego użytkownika Brain-Flak. Trzeba trochę przyzwyczaić się i wymaga zmiany sposobu myślenia o programowaniu w Brain-Flak, ale przy odpowiednim użyciu robi różnicę między przyzwoitym a niesamowitym, jeśli chodzi o golfa.
Ściągawka
Oto lista operacji i ich wpływu na trzeci stos
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