Vi presento con orgoglio ...
<}74}}:23}29}59}}}}}}}:111_}}}}:::::::23_}:111
? @
:" }}_47}_95 3""""""""(
_ : } _ } {=}
2 23_}29_ _ ; : \
0 ; 3 +_( 3_" 60{ .{.{.
"-_95:}}"" 2 0 ) 2 " _ _ {
"" _ : 2 _ ."(; } 3 .{
;_92}_47} : _ 0 = : * ;
: "" 2 {.{{ . -""(
}}:59_}}:::: "";_ . { _ "
} " {.{.{. 32.
}}}_95:}}}}_20-
... il mio nuovo esolang bidimensionale Labyrinth! Il codice sopra non è incredibilmente ben golfato (ci sono 161 spazi e 25 NOP, quindi un layout migliore potrebbe abbreviare molto questo), ma almeno sono riuscito a dimostrare che il linguaggio è utilizzabile per attività non banali. :)
Come funziona
Innanzitutto, una rapida panoramica della lingua:
- Labyrinth opera su due pile, principale e ausiliaria , che può contenere numeri interi con segno arbitrario. Nella parte inferiore di entrambe le pile c'è una quantità infinita di zero.
- I comandi sono singoli personaggi su una griglia 2D e formano un labirinto (ovvero i caratteri sconosciuti, in particolare gli spazi, sono muri).
"è un NOP che non è un muro e può essere utile per riempire determinati percorsi nel codice. A differenza di molti altri linguaggi 2D, i bordi non si avvolgono.
- Il puntatore dell'istruzione (IP) inizia dal primo carattere non a muro (in ordine di lettura) spostandosi verso destra.
@termina il programma.
- Se possibile, l'IP segue i corridoi (anche attorno alle curve). Se l'IP ha più celle su cui spostarsi, generalmente girerà a sinistra se la parte superiore dello stack principale è negativa, si sposta in avanti se è zero o gira a destra se è positiva. Quando l'IP colpisce un muro, inverte la direzione. (Ci sono alcune altre sottigliezze, ma non dovrebbero importare per questo codice.) Questo è l'unico modo per implementare il flusso di controllo.
- Oltre ai comandi di manipolazione aritmetica e dello stack, il codice sorgente può essere modificato in fase di esecuzione con i quattro comandi
>v<^ che sposteranno ciclicamente una riga o colonna del codice sorgente di una cella. La riga o colonna interessata dipende dalla parte superiore della pila. Se la riga o colonna dell'IP viene spostata, si sposterà con lo spostamento. Ciò consente di saltare da un bordo all'altro del codice sorgente.
Ora per questa sfida particolare, ecco l'idea generale dell'algoritmo:
- Spingere le estremità delle auto verso i cofani (es
/ \_o oo o ) Sulla pila ausiliaria.
- Leggi l'input e determina se spingere
__ o /\successivo.
- Spingere il resto delle auto (es
__ __ _/ \ e due spazi iniziali) sulla pila ausiliaria.
- Blocca l'input su un valore massimo di
20, chiamiamolo N .
- Ora esegui le seguenti 3 volte:
- Stampa N spazi.
- Stampa 6 caratteri memorizzati.
- Stampa 60 - 3 * N spazi.
- Stampa 6 caratteri memorizzati.
- Stampa una nuova riga.
Infine, diamo un'occhiata ad alcune parti del codice. L'IP inizia nell'angolo in alto a sinistra, con un comando di spostamento della griglia. La parte superiore dello stack principale è 0(che viene utilizzata come indice relativo), quindi la prima riga viene spostata a sinistra, il che sposta anche l'IP all'estremità destra della griglia. Ora la prima riga viene semplicemente eseguita da destra a sinistra, il che spinge il primo set di caratteri fissi sullo stack ausiliario:
}74}}:23}29}59}}}}}}}:111_}}}}:::::::23_}:111<
Questo spostamento di riga è utile per giocare a golf quando si desidera iniziare con una grande quantità di codice lineare.
Quindi leggiamo l'ingresso e spingiamo i cofani corretti:
?
:"
_
2
0 ;
"-_95:}}""
"" _
;_92}_47}
Il bit a sinistra con i tre NOP invia risultati negativi lungo il ramo superiore e risultati non negativi lungo il ramo inferiore. A destra sono riuniti insieme.
Ora segue un'altra grande sezione lineare (che probabilmente potrebbe essere giocata a golf molto con un altro trucco che sposta le file):
}}_47}_95
: }
23_}29_ _
3
2
:
:
:
}}:59_}}::::
}
}}}_95:}}}}
Questo spinge il resto delle auto sulla pila ausiliaria.
Quindi, calcoliamo min(20, input), che è simile al primo ramo:
;
+_(
0 )
2 _
_ 0
"" 2
"";_
"
_20-
Infine, abbiamo il ciclo che viene eseguito tre volte per stampare le linee. Ogni iterazione del loop contiene due piccoli (3x3) loop per stampare gli spazi, nonché due sezioni per stampare 6 caratteri dalla pila ausiliaria:
@
3""""""""(
_ } {=}
: \
3_" 60{ .{.{.
2 " _ _ {
."(; } 3 .{
= : * ;
{.{{ . -""(
. { _ "
{.{.{. 32.
Un trucco ingegnoso a cui vorrei attirare l'attenzione è quello .{.{.sul bordo destro. Questo è un vicolo cieco, quindi a parte .la fine il codice viene eseguito due volte, una volta in avanti e una volta all'indietro. Questo offre un modo accurato per abbreviare il codice palindromico (il problema è che è necessario assicurarsi che l'IP faccia la svolta corretta quando si esce di nuovo dal vicolo cieco).
/ \anziché abbassati_ _?