Suggerimenti per giocare a golf in Brachylog


19

Brachylog è un linguaggio che sta cominciando a diventare sempre più importante nel golf del codice di recente (e ha appena ricevuto un importante aggiornamento con una sintassi terser). Come Prolog, ha il vantaggio di poter spesso risolvere un problema (in genere tramite la forza bruta) semplicemente da una descrizione sufficientemente accurata di come si presenta un problema, una caratteristica che significa che sul giusto tipo di sfida, è spesso paragonabile al le migliori lingue di golf (ed è stato conosciuto per battere Jelly di volta in volta).

Quali consigli hai per giocare a golf (ovvero scrivere i programmi più brevi possibili) in Brachylog? Questo è principalmente alla ricerca di consigli specifici per Brachylog in particolare, piuttosto che consigli applicabili a una vasta gamma di lingue. (I consigli sul golf nelle lingue dichiarative in generale potrebbero potenzialmente essere appropriati qui, a seconda di quanta applicazione dovranno avere in lingue diverse da Brachylog, anche se vedi anche Suggerimenti per il golf in Prolog .)

Risposte:


4

Sfrutta i predicati nidificati per creare nuove variabili

Brachylog ha molti casi speciali di sintassi per rendere le sue due variabili speciali, ?(parametro input / left) e .(parametro output / right), più facili da usare. Ciò significa che se non è necessario accedere al predicato ?e ., ma è necessario utilizzare le variabili, è spesso possibile salvare byte creando un predicato nidificato per utilizzare il suo ? e ..

Come semplice esempio, considera un programma simile al seguente:

… A … ∧A … B … B …

Questa è una forma abbastanza comune per un programma più lungo; dopo tutto, ci sono molte lacune che potrebbero contenere qualsiasi cosa. Supponiamo di non aver bisogno ?o .all'interno del centro di tre spazi vuoti. Quindi potremmo riscriverlo in questo modo:

… { … & … . … } …

Qui, il predicato nidificato ?serve al ruolo di Ae .il ruolo di B. Possiamo osservare che questo è un byte più corto del codice originale; il passaggio AABBa {?.}non ha alcun cambiamento in termini di byte, ma ciò ci ha permesso di semplificare ∧?l'abbreviazione &.

Un trucco correlato è quello di cambiare

∧. … ?∧

per

~{ … }

(che è un byte più breve), sebbene si noti che è quasi sempre più economico convincere il chiamante a scambiare gli argomenti (a meno che il predicato non venga chiamato da almeno tre diverse posizioni nel programma, cosa rara in Brachylog).


3

Suddividi i predicati di lunghezza 2 all'interno dei metapredicati

Questo è meglio spiegato con l'esempio. Per rimuovere il primo e l'ultimo elemento di un elenco, lo decapitiamo e lo tagliamo:

bk

Se volessimo eseguire questa operazione su ogni elemento di un elenco, possiamo usare un'operazione cartografica:

{bk}ᵐ

Tuttavia, è un byte più breve per dividere il predicato in due e mappare ciascuna parte separatamente:

bᵐkᵐ

Lo stesso trucco può essere utilizzato con parecchi metapredicati:

{bk}ᵐ  →  bᵐkᵐ
{bk}ˢ  →  bˢkˢ
{bk}ᶠ  →  bᶠkˢ
~{bk}  →  ~k~b

Nota che per alcuni metapredicati, ad esempio , non esiste un modo generico di dividerlo in due parti, ma potrebbe essere comunque possibile trovare una decomposizione che funzioni per l'attività specifica su cui stai lavorando.


3

Trasmissione dell'elenco vuoto sulla stringa vuota

A volte, quando si lavora con le stringhe, l'algoritmo che utilizziamo potrebbe unificare ciò che vogliamo con l'elenco vuoto [], quando vorremmo piuttosto la stringa vuota "".

È possibile eseguire il cast dell'elenco vuoto sulla stringa vuota usando ,Ẹ, che aggiunge la stringa vuota alla sua variabile sinistra (questo è un exploit del modo in cui ,viene implementato).

Ciò ha anche il vantaggio di non fare nulla se la variabile di sinistra è una stringa. Quindi, se il tuo programma lo è

{  
   some predicate that should always output a string, 
   but actually outputs [] instead of "" in specific cases
}

Poi

{
  some predicate that should always output a string, 
  but actually outputs [] instead of "" in specific cases
},Ẹ

funzionerà nel modo desiderato.


2

L'elemento singolo viene eseguito in un elenco

Considera questo frammento:

ḅ∋≠

Se l'input è un elenco o una stringa, l'output è unificato con un elenco secondario / sottostringa di lunghezza 1 che non fa parte di un ciclo più lungo di elementi uguali. Divide l'elenco in blocchi di elementi uguali e trova un blocco i cui elementi sono tutti diversi. Per ottenere gli elementi stessi invece degli elenchi singleton, virare hfino alla fine. Ho usato questo costrutto qui con oper trovare un personaggio che si verifica solo una volta nella stringa di input.

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.