Alcuni consigli qui:
costanti:
La pagina delle costanti degli Esolang contiene un elenco estremamente utile dei modi più brevi per creare valori specifici. Mi ritrovo a consultare questa pagina almeno due volte per programma.
L'inizio di tutto:
+++[[<+>>++<-]>]
Questo imposta il nastro nel formato 3 * n ^ 2, che sembra
3 6 12 24 48 96 192 128 0 0 '
Perché è così importante?
Scendiamo l'elenco:
- 3 e 6 sono noiosi
- 12: vicino a 10 (newline) o 13 (ritorno a capo). Può essere utilizzato anche per il contatore per 0-9
- 24: vicino a 26, il numero di lettere dell'alfabeto
- 48: ASCII per
0
- 96: vicino a 97, ASCII per
a
- 196 e 128: 196-128 = 64, vicino a 65, ASCII per
A
.
Da questo unico algoritmo, siamo all'inizio praticamente di ogni sequenza nell'intervallo ASCII, insieme a un contatore per ciascuno e una nuova riga a portata di mano.
Un esempio pratico:
Stampa di tutte le lettere maiuscole e minuscole e cifre.
Con algoritmo:
+++[[<+>>++<-]>]<<[-<->]<<<<++[->>+.>+.<<<]<--[>>.+<<-]
Senza:
+++++++++++++[->+++++++>++>+++++>++++>+<<<<<]>+++++>[-<+.>>.+<]>>---->---[-<.+>]
Spendiamo la maggior parte dei byte solo inizializzando il nastro nel secondo esempio. Alcuni di questi sono compensati dai movimenti extra nel primo esempio, ma questo metodo ha chiaramente il vantaggio.
Un paio di altri algoritmi interessanti nella stessa vena:
3 * 2 ^ n + 1:
+++[[<+>>++<-]+>]
Tape: 4 7 13 25 49 65 197 129 1 0'
Ciò compensa i valori di 1, il che compie alcune cose. Rende il 12 un ritorno a capo, il 64 l'inizio effettivo dell'alfabeto maiuscolo e il 24 più vicino a 26.
2 ^ n:
+[[<+>>++<-]>]
Tape: 1 2 4 8 16 32 64 128
Poiché 64 è valido per lettere maiuscole, 32 è ASCII per spazio e 128 può essere utilizzato come contatore per 26 (130/5 = 26). Ciò può salvare byte in determinate situazioni in cui non sono necessarie cifre e lettere minuscole.
Scegli l'implementazione adatta alla domanda:
- Le celle negative sono quasi sempre utili e non c'è motivo di evitarle (a meno che non cambi il tuo conto)
- Quasi la stessa cosa con le celle di avvolgimento, ancora di più perché molte costanti usano il wrapping.
- Le dimensioni arbitrarie delle celle sono utili per infinite sequenze matematiche, come il calcolo infinito della sequenza di Fibonacci (
+[[-<+>>+>+<<]>]
) o l'elaborazione di numeri più grandi / negativi. Il rovescio della medaglia è che alcuni metodi comuni, come [-]
e [->+<]
non possono essere fatti valere, nel caso in cui il numero sia negativo.
- EOF come 0, -1 o nessuna modifica. Di solito è preferibile 0, in quanto è possibile eseguire il ciclo su un intero input senza ulteriori controlli. -1 è utile quando si esegue il ciclo su strutture di array. Non ho ancora trovato un uso per nessun cambiamento :(.
Tieni traccia di ciò che sta succedendo:
In ogni momento dovresti avere commenti su dove dovrebbe essere il puntatore in relazione ai dati che lo circondano e assicurarti di conoscere l'intervallo dei possibili valori di ogni cella. Questo è particolarmente importante quando hai diviso il puntatore prima di un ciclo, perché dopo vorrai unire nuovamente le due possibilità.
In ogni momento, il mio codice è pieno di commenti su ogni altra riga che assomigliano a questo:
*0 *dat a_1 ? 0' !0 0*
or
*0 *dat 0' ap1 0 !0 0*
Un altro consiglio è quello di assegnare significati speciali ai simboli. Nell'esempio sopra, '
è dove si trova il puntatore, *
significa ripetizione in quella direzione, ?
significa una cella con valore sconosciuto, !0
significa una cella diversa da zero, _
è un sostituto -
ed p
è un sostituto +
. or
implica che il nastro potrebbe apparire come una delle rappresentazioni e deve essere gestito come tale.
Il tuo schema di simboli non deve necessariamente essere uguale al mio (che ha alcuni difetti), deve solo essere coerente. Questo è anche estremamente utile durante il debug, perché è possibile eseguirlo fino a quel punto e confrontare il nastro effettivo con quello che si dovrebbe avere, il che può evidenziare potenziali difetti nel codice.