Suggerimenti per giocare a golf in Underload


11

Underload è un tarpit semi-funzionale basato su stack creato da ais523 . Di recente ho provato a giocare a golf, in quanto è un linguaggio sorprendentemente elegante.

Quali consigli hai per giocare a golf in Underload? (Un consiglio per risposta)


Mi piace che l'unica forma di flusso di controllo sia un evalcomando, non ho mai visto un linguaggio come quello prima.
ETHproductions

Risposte:


3

Utilizzare *per l'output

Poiché è possibile eseguire l'output lasciando una stringa nello stack , potrebbe essere utile accumulare la stringa utilizzando *invece di eseguire l' output con S. Supponiamo che la tua sfida sia "prendere una stringa e aggiungere uno spazio", il modo per farlo con l'output sarebbe:

S( )S

Il modo per farlo *, d'altra parte è un byte più breve:

( )*

Il problema è che se l'output ha molti accumuli, potrebbe costare byte gestire l'elemento di output nello stack.


2

Utilizzare un dizionario di funzioni riutilizzate ripetutamente

Se devi usare molto un pezzo di codice, ha senso archiviarlo nello stack e duplicarlo e valutarlo di tanto in tanto. Finora, questa è solo la normale programmazione di Underload. Sfortunatamente, mantenere un valore nello stack per lungo tempo è difficile e tende a rendere il codice dettagliato, e questo è vero anche se il valore è una funzione piuttosto che dati. Questo peggiora molto se hai più funzioni che devono essere riutilizzate ripetutamente.

Nel tipo di programma più grande che potrebbe trarre vantaggio da diverse funzioni riutilizzate, una soluzione che puoi utilizzare è invece quella di creare una funzione di grandi dimensioni in grado di adempiere a qualsiasi dei loro scopi a seconda del modo in cui viene chiamata (in base a ciò che è sotto nello stack, o tramite utilizzando più chiamare sequenze che solo ^; una funzione scritto con cura in grado di distinguere ^^da ^:^da^*^ da ^~^, dandovi quattro distinti, piuttosto brevi sequenze). In questo "dizionario" puoi anche memorizzare altre cose utili, come le stringhe che usi più volte. Nota che se usi il dizionario pesantemente, può avere senso trasformarlo in una specie di quine, spingendo una copia di se stesso nello stack, in modo che non sia necessario copiarlo manualmente con: essere in grado di usarlo senza perdere la capacità di usarlo in futuro.


Sarei impazzito molto prima di avere un programma abbastanza grande in Underload che questo diventasse un problema: P
Esolanging Fruit

Una volta ho scritto alcuni esempi sulla pagina di esolangs su come fare dizionari con la mia ^!!!!^ricerca di stile preferita (che ho anche usato in molti altri esempi sulla pagina, specialmente nella sezione di minimizzazione). Anche se questo potrebbe non dare la ricerca più breve.
Ørjan Johansen,

2

Scegli formati di dati specializzati per le operazioni di cui il problema ha bisogno

Come semplice esempio, l'implementazione più comunemente vista dei booleani è !()per false (cioè intero 0) e la stringa nulla per vero (cioè intero 1), ma se si riscontra un problema fortemente basato su XOR logico, si potrebbe fare di più ha senso usare la stringa null per false e ~per true (questo formato di dati può essere convertito in qualsiasi altro formato booleano usando (false)~(true)~^!e consente un'implementazione molto concisa *per XOR.

È possibile approfondire ulteriormente questo principio generale e utilizzare le funzioni di cui il programma avrà bisogno in seguito come parte dei valori dei dati; che evita di dover memorizzare le funzioni e i dati separatamente nello stack. Questo può rendere il flusso di controllo un po 'più confuso, ma quando si gioca a golf, la manutenibilità deve spesso passare in secondo piano, e non è comunque possibile che Underload sia tutto ciò utilizzabile.


Ho usato per usare (!)e (~!)per booleani, ma la tua strada sembra migliore.
Esolanging Fruit

2

Decremento "sporco"

Il modo funzionale puro di decrementare un numero di Church è di usare la funzione predecessore del calcolo lambda:

\n.n(\p.\z.z($(pT))(pT))(\z.z0[whatever you define the predecessor of 0 to be])

Dove 0 = \ x. \ Yy, T = \ x. \ Yx e $ è il successore.

Riscritto in Underload, si tratta di 28 byte:

(!())~(!())~(!:(:)~*(*)*~)~^!

Questo va bene, ma siamo in grado di sfruttare alcune delle proprietà utili di sottocarico, vale a dire che :!e ()*fare sono no-ops. Ciò significa che, per un numero n, :ⁿ!!()()*ⁿ(dove cⁿsi cripetono i ntempi) si ottiene n-1. Ad esempio, facendo questo per il numero 3 della Chiesa si ottiene questo:

:::!!()()***

Rimuovendo le coppie no-op, otteniamo:

:*

Che è 2.

Quindi questa è la nuova e più breve operazione precedente:

:(:)~^(!!()())*~(*)~^*

Si tratta di 7 byte in meno.


Ciò si interrompe su n = 0 però. Se hai bisogno che funzioni, (()~(:))~:(^!!())*~(*)~^** è ancora più corto di 3 byte.
Ørjan Johansen,

@ ØrjanJohansen In generale, avresti un caso speciale per n = 0, perché con i numeri di Underload che diminuiscono 0 non ha comunque senso.
Esolanging Fruit

1

Inserire i valori dello stack non necessari nello spazio del programma

Underload ha in realtà due stack: lo stack di stringhe e lo stack di comandi che compongono il codice sorgente. Le ^istruzioni di Underload ci consentono di spostare le stringhe dal primo stack al secondo. In questo modo, possiamo risparmiare molte manipolazioni dello stack non necessarie.

Ad esempio, supponiamo di avere (a)(b)(c)nello stack principale e che vorremmo concatenare i due elementi inferiori, ignorando (c), per ottenere (ab)(c). Il modo ingenuo per farlo è ruotare la pila per ottenere (c)(a)(b)e quindi concantenare e scambiare:

a~a~*~a*^*~

Questo non va bene. L'uso a~a~*~a*^per ruotare la pila in questo modo è estremamente costoso e dovrebbe essere evitato quando possibile. Mettendo (c)invece nello spazio del programma, questo può essere ridotto di quattro byte:

a(*)~*^

L'idea è di prendere le istruzioni che si desidera eseguire e quindi aggiungere un'istruzione per respingere (c)alla fine, quindi valutare il risultato. Ciò significa che non dobbiamo preoccuparci (c)fino a quando non viene respinto dopo che abbiamo finito.


1
Puoi anche scriverlo come (*)~a*^, che penso sia un po 'più compostabile. Essenzialmente ~a*^è il dipcomando di Gioia.
Ørjan Johansen
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.