Usa il terzo stack
Se hai letto il titolo potresti essere un po 'confuso. Sicuramente ci sono solo due pile in Brain-Flak? Comunque ti assicuro che esiste ed è uno degli strumenti più potenti se non il più potente nella scrittura e nel golf di Brain-Flak.
Che cos'è il "terzo stack"?
Ogni programma Brain-Flak utilizza il terzo stack in un modo o nell'altro, ma la maggior parte dell'utilizzo continua dietro le quinte ed è spesso utile semplicemente ignorare il fatto che esiste. Ogni parentesi nel programma aggiunge o rimuove un oggetto dalla pila. Tre delle parentesi graffe aperte ([<
aggiungono tutti un oggetto alla pila, mentre i loro tre coniugati )]>
rimuovono tutti un oggetto dalla pila. Il valore dell'elemento nello stack è il valore dell'ambito corrente del programma e l'utilizzo di nilad modifica questo valore in alcuni modi. La parentesi stretta )
ha la funzione unica di spostare un elemento dalla terza pila alla pila corrente; una spinta.
Spero che questo ti stia diventando chiaro. Il terzo stack è una sorta di stack che ricorda i valori di ritorno del codice che è già stato eseguito. Esaminiamo un esempio di un semplice programma che tiene traccia delle due pile normali e della terza pila.
Esempio
Cammineremo attraverso il seguente programma. Questo programma viene inserito -3, 1, -2
nello stack.
(([()()()])(()))
Iniziamo con tre parentesi graffe aperte, che spingono tutte a zero al terzo stack.
Le nostre pile ora sembrano così, la terza pila è quella a destra e la pila attiva ha un ^
sotto:
0
0
0 0 0
^
(([()()()])(()))
^
Ora abbiamo tre ()
nilad. Questi non fanno nulla alle normali due pile, tuttavia ognuna ne aggiunge una all'inizio del terzo stack facendo apparire le nostre pile come:
3
0
0 0 0
^
(([()()()])(()))
^
Ora incontriamo un ]
come indicato prima che le parentesi graffe chiuse rimuovano un oggetto dalla terza pila, ma ]
ha la funzione di sottrarre l'elemento che rimuove dalla cima della pila. Quindi le nostre nuove pile appariranno come:
-3
0 0 0
^
(([()()()])(()))
^
Questo ha senso; [...]
fa negazione, quindi ]
dovrebbe sottrarre verso il basso.
Ora dobbiamo eseguire un )
. Come probabilmente ricorderai )
è il posto nel programma in cui le cose vengono spinte nello stack, quindi sposteremo la parte superiore del terzo stack nello stack corrente, inoltre aggiungeremo l' -3
elemento successivo al terzo stack.
-3 0 -3
^
(([()()()])(()))
^
Ancora una volta incontriamo una delle nostre tre parentesi graffe aperte, quindi aggiungeremo un altro elemento al nostro terzo stack.
0
-3 0 -3
^
(([()()()])(()))
^
Come abbiamo detto in precedenza ()
aumenterà la parte superiore del nostro terzo stack di uno.
1
-3 0 -3
^
(([()()()])(()))
^
E )
si muoverà la parte superiore del Terzo Stack nello stack e aggiungere il basso attivi
1
-3 0 -2
^
(([()()()])(()))
^
L'ultimo )
sposta il Terzo Stack nello stack attivo e poiché non ci sono elementi rimasti nel Terzo Stack da aggiungere, non fa altro.
-2
1
-3 0
^
(([()()()])(()))
^
Il programma è finito, quindi terminiamo e produciamo.
Questo esempio ha lo scopo di darti un'idea di ciò che è e fa la terza pila. Non include tutte le operazioni, ma si spera che tu possa capire cosa ciascuna di esse fa da sola. Se stai ancora lottando, ho incluso un "cheatsheet" in fondo a questa risposta per aiutarti.
Ok, allora?
Ok, ora capisci il terzo stack, ma "E allora?" Lo stavi già utilizzando anche se non lo chiamavi "Terzo Stack", in che modo pensare in termini di Terzo Stack ti aiuta a giocare a golf?
Vediamo un problema. Vuoi prendere il triangolo di un numero . Questa è la somma di tutti i numeri inferiori a n.
Un approccio potrebbe essere quello di creare un accumulatore fuori dallo stack e aggiungerlo durante il conto alla rovescia. Questo crea un codice simile al seguente:
(<>)<>{(({}[()])()<>{})<>}{}<>({}<>)
Provalo online!
Questo codice è piuttosto compatto e si potrebbe pensare che non possa essere molto più piccolo. Tuttavia, se lo affrontiamo da un terzo punto di vista dello stack, diventa chiaro che questo è gravemente inefficiente. Invece di mettere il nostro accumulatore nello stack, possiamo metterlo sul terzo stack con a (
e recuperarlo alla fine che usiamo )
. Riprogrammeremo ancora una volta tutti i numeri, ma questa volta non dobbiamo fare molto per aumentare il nostro terzo stack, il programma lo fa per noi. Questo sembra:
({()({}[()])}{})
Provalo online
Questo codice ha meno della metà delle dimensioni della versione abbastanza ben giocata prima. In effetti, una ricerca al computer ha dimostrato che questo programma è il programma più breve possibile in grado di eseguire questa attività. Questo programma può essere spiegato usando l'approccio "somma di tutte le esecuzioni", ma penso che sia molto più intuitivo e chiaro quando spiegato con un approccio di terzo stack.
Quando uso il terzo stack?
Idealmente, ogni volta che inizi a lavorare su un nuovo problema in Brain-Flak, dovresti pensare a te stesso come farei pensando alla terza pila. Tuttavia, come regola generale ogni volta che devi tenere traccia di un qualche tipo di accumulatore o avere un totale parziale, è una buona idea provare a metterlo sul tuo terzo stack anziché sulle due pile reali.
Un'altra volta che potrebbe essere una buona idea considerare l'utilizzo del terzo stack è quando non si ha spazio per memorizzare un valore sugli altri due stack. Ciò può essere particolarmente utile quando si eseguono manipolazioni su due stack esistenti e si desidera salvare un valore per un uso successivo senza dover tenere traccia di dove si trova.
Limitazioni del terzo stack
Il terzo stack è molto potente in molti modi, ma ha i suoi limiti e svantaggi.
Innanzitutto, l'altezza massima della pila per la terza pila in un dato punto viene determinata al momento della compilazione. Ciò significa che se si desidera utilizzare una quantità di spazio nello stack, è necessario allocare tale spazio durante la scrittura del programma.
In secondo luogo, il terzo stack non è un accesso casuale. Ciò significa che non è possibile eseguire alcuna operazione su alcun valore ma sul valore più elevato. Inoltre, non è possibile spostare valori nello stack (diciamo scambiare i primi due elementi).
Conclusione
Il terzo stack è uno strumento potente e lo considero essenziale per ogni utente Brain-Flak. Ci vuole un po 'per abituarsi e richiede un cambiamento nel modo in cui pensi alla programmazione in Brain-Flak, ma se usato correttamente fa la differenza tra un discreto e uno straordinario quando si tratta di golf.
Cheatsheet
Ecco un elenco di operazioni e di come influenzano il terzo stack
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