Questa è la prima delle numerose sfide per il compleanno di Brain-Flak progettate per celebrare il primo compleanno di Brain-Flak! Puoi trovare maggiori informazioni sul compleanno di Brain-Flak qui
L'estate scorsa abbiamo avuto il Brain-flak Integer Metagolf , e da allora le risposte che ha generato sono state molto utili alla comunità Brain-Flak. La cosa principale che rende Integer Metagolf così efficiente è una tecnica chiamata hardcoding con moltiplicazione.
In Brain-Flak la moltiplicazione del runtime è estremamente costosa. Lo snippet di moltiplicazione più breve noto è:
({}<>)({<({}[()])><>({})<>}{}<><{}>)
Scoperto da Megatom
Tuttavia, esiste un modo molto semplice per creare la moltiplicazione del tempo di compilazione. Ad esempio il seguente codice si moltiplica per 5:
(({})({})({})({}){})
Questo funziona perché le espressioni consecutive vengono sommate. Ognuno ({})
non fa nulla per lo stack (si {}
apre e lo (..)
spinge indietro) e valuta ciò che è in cima allo stack. Tutte queste espressioni insieme sommano fino a cinque volte tutto ciò che era in cima alla pila.
Per qualsiasi n
la seguente espressione di stringa creerà uno snippet che moltiplicherà la parte superiore dello stack per n
:
"("+"({})"*(n-1)+"{})"
Funziona creando n
espressioni che valutano tutte in cima alla pila. Il primo in n-1
realtà non cambia nulla e l'ultimo rimuove la parte superiore dello stack prima del push.
Per i numeri compositi è possibile concatenare più espressioni più piccole per salvare byte. Ad esempio puoi moltiplicare per 25 moltiplicando per 5 due volte:
(({})({})({})({}){})(({})({})({})({}){})
Questo è piuttosto semplice e per alcuni numeri funziona abbastanza bene, tuttavia ci sono modi migliori per farlo. Ad esempio, un metodo che mi è venuto in mente utilizza la rappresentazione binaria del numero. ( Ecco un'implementazione di Python ) Questo nuovo metodo è molto più efficace della semplice espressione di stringa mostrata in precedenza, ma non è la fine, ci sono molti modi interessanti per moltiplicare hardcode e probabilmente una tonnellata che nessuno ha ancora scoperto.
Quindi penso che sia tempo di vedere quanto possiamo essere bravi.
Breve panoramica di Brain-Flak
Ecco una descrizione di tutto ciò che devi sapere su Brain-Flak per questa sfida.
Brain-Flak ha "nilads" e "monads". I nilad sono parentesi che non hanno nulla al loro interno. Ogni nilad fa una cosa e restituisce un valore. Per questa sfida i due nilad di cui ci occupiamo sono {}
e <>
. {}
apre la parte superiore dello stack attivo e restituisce il suo valore. <>
cambia lo stack attivo e lo stack attivo, in modo che lo stack attivo diventi inattivo e lo stack inattivo diventi attivo, restituisce zero.
Le monadi sono parentesi con cose al loro interno. Prendono un singolo argomento, la somma di tutto ciò che contiene, a volte eseguono un'azione e quindi restituiscono un valore. Tutti e tre questi ci occupiamo sono (...)
, <...>
e [...]
. La monade più importante per questa sfida (...)
prende il valore dell'interno e lo spinge nello stack attivo. Quindi restituisce l'argomento. <...>
e [...]
sono entrambe monadi "inerti", ovvero non eseguono alcuna azione ma modificano piuttosto il valore che vengono passati. <...>
restituisce sempre zero indipendentemente dall'argomento passato. Nel frattempo [...]
restituisce sempre i tempi degli argomenti -1
.
Programmi di esempio con spiegazione
Se non hai mai programmato in Brain-Flak, potrebbe essere una buona idea guardare alcuni programmi di esempio usando le operazioni descritte
({}{})
Questo aggiunge i primi due numeri nello stack. Ognuno {}
estrae un valore dallo stack e (...)
rimanda la loro somma indietro.
({}[{}])
Allo stesso modo, questo sottrae il secondo oggetto nello stack dal primo. Come prima di ogni {}
pop-up di un valore, ma [..]
intorno al secondo viene aggiunto. Ancora una volta (...)
spinge la somma.
({}<{}>)
Ciò rimuove il secondo valore nello stack mantenendo intatto il valore superiore. Funziona proprio come gli ultimi due, tranne per il fatto che il secondo valore è messo a tacere da <...>
così il push spinge indietro solo il primo valore.
(({}))
Questo crea una seconda copia del valore nella parte superiore dello stack. Lo fa saltando in cima allo stack e {}
ottenendo il suo valore, il primo (..)
lo spinge indietro valutando il suo valore. Il secondo (...)
prende il valore restituito dal primo e lo spinge anche nello stack. creando una seconda copia.
Compito
Dato un numero intero, n
crea uno snippet Brain-Flak pulito dallo stack che moltiplica la parte superiore dello stack corrente per n
.
Puoi usare le seguenti operazioni Brain-Flak
(...) -> Push Monad, Pushes the result of its contents
<...> -> Zero Monad, Returns zero
[...] -> Negative Monad, Returns the opposite of its contents result
{} -> Pop nilad, Pops the TOS and returns its value
<> -> Switch nilad, Switches the active and inactive stack
Le altre operazioni sono vietate ai fini della sfida.
punteggio
Il tuo punteggio sarà la lunghezza cumulativa di tutti i programmi da n=2
a n=10000
. Assicurati di includere un link all'output del tuo programma per la verifica.
[...]
, quindi è un inizio.