Brainflak Moltiplicazione Metagolf


17

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:

 (({})({})({})({}){})

Provalo online!

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 nla seguente espressione di stringa creerà uno snippet che moltiplicherà la parte superiore dello stack per n:

"("+"({})"*(n-1)+"{})"

Funziona creando nespressioni che valutano tutte in cima alla pila. Il primo in n-1realtà 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, ncrea 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=2a n=10000. Assicurati di includere un link all'output del tuo programma per la verifica.


1
Per interesse, perché le operazioni 1 e loop sono vietate?
Neil,

@Neil Anche l'operatore di altezza dello stack è vietato.
Erik the Outgolfer,

1
@EriktheOutgolfer Avevo già vietato comunque quello nel metagolf intero.
Neil,

7
Gli informatici sono strani. Inventano linguaggi di programmazione impossibili da usare, intrinsecamente anti-golf, e poi si sfidano a scrivere codice golfizzato per risolvere semplici problemi in questo linguaggio. Niente è più esoterico di questo. +1 bravo signore.
Draco18s non si fida più di SE

1
@ Qwerp-Derp Ho cercato di ottimizzare l'output del programma Python collegato (punteggio attuale 681950) e ho trovato un banale risparmio di 4492 usando [...], quindi è un inizio.
Neil,

Risposte:


2

Rubino, 669856

$answers = Hash.new{|hash,n|
  valid = []
  2.upto(n**0.5){|i|
    valid.push("("+hash[n/i]+")"+"({})"*(i-2)+"{}") if n%i == 0
  }
  valid.push("({})"+hash[n-1])
  (hash[n] = valid.min_by{|s| s.length})
}
$answers[1] = "{}"

def full_answer n
  "("+$answers[n]+")"
end

Questa è una risposta di base rapida. Primi 1000 min-programmi trovati qui . (Ho provato a postarli tutti, ma questo ha sovraccaricato la dimensione massima di pastebin.) Potrei aggiungere una spiegazione del codice in seguito.

Esempi:

360:    ((((((({})(({}){}){})({}){})({}){}){}){}){})
4608:   (((((((((((({})({}){})({}){}){}){}){}){}){}){}){}){}){})
9991:   (({})((({})(((((((({})((({})({}){}){}){}){}){}){}){}){}){}){})({}){}){})
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.