:?
:
#/)
\ #
!"*@
"
Provalo online!
Questo genera i risultati nell'ordine C, B, A separato da avanzamenti di riga.
Spiegazione
Come al solito, un breve primer Labyrinth:
- Labyrinth ha due pile di numeri interi di precisione arbitraria, main e aux (iliary), che inizialmente sono riempiti con una quantità (implicita) infinita di zeri. Useremo solo main per questa risposta.
- Il codice sorgente assomiglia a un labirinto, in cui il puntatore dell'istruzione (IP) segue i corridoi quando può (anche dietro gli angoli). Il codice inizia dal primo carattere valido nell'ordine di lettura, ovvero nell'angolo in alto a sinistra in questo caso. Quando l'IP arriva a qualsiasi forma di giunzione (cioè diverse celle adiacenti oltre a quella da cui proviene), sceglierà una direzione basata sulla parte superiore dello stack principale. Le regole di base sono: girare a sinistra quando è negativo, andare avanti quando è zero, girare a destra quando è positivo. E quando uno di questi non è possibile perché c'è un muro, l'IP prenderà la direzione opposta. L'IP si gira anche quando colpisce i vicoli ciechi.
Nonostante i due no-op ( ") che rendono il layout un po 'dispendioso, sono abbastanza contento di questa soluzione, perché il suo flusso di controllo è in realtà abbastanza sottile.
L'IP inizia nell'angolo in alto a sinistra sulla :destra. Colpirà immediatamente un vicolo cieco sul ?e si girerà, in modo che il programma inizi effettivamente con questo pezzo lineare di codice:
: Duplicate top of main stack. This will duplicate one of the implicit zeros
at the bottom. While this may seem like a no-op it actually increases
the stack depth to 1, because the duplicated zero is *explicit*.
? Read n and push it onto main.
: Duplicate.
: Duplicate.
Ciò significa che ora abbiamo tre copie dello nstack principale, ma la sua profondità è 4. Questo è conveniente perché significa che possiamo profondità dello stack per recuperare il moltiplicatore corrente mentre lavoriamo attraverso le copie dell'input.
L'IP ora entra in un ciclo 3x3 (in senso orario). Si noti che #, che spinge la profondità dello stack, spingerà sempre un valore positivo in modo tale che sappiamo che a questo punto l'IP girerà sempre verso est.
Il corpo del loop è questo:
# Push the stack depth, i.e. the current multiplier k.
/ Compute n / k (rounding down).
) Increment.
# Push the stack depth again (this is still k).
* Multiply. So we've now computed (n/k+1)*k, which is the number
we're looking for. Note that this number is always positive so
we're guaranteed that the IP turns west to continue the loop.
" No-op.
! Print result. If we've still got copies of n left, the top of the
stack is positive, so the IP turns north and does another round.
Otherwise, see below...
\ Print a linefeed.
Then we enter the next loop iteration.
Dopo che il ciclo è stato attraversato (fino a !) tre volte, tutte le copie di nvengono esaurite e viene rivelato lo zero sottostante. Dovuto al" del fondo (che altrimenti sembra piuttosto inutile) questa posizione è un incrocio. Ciò significa che con uno zero in cima allo stack, l'IP cerca di andare dritto (ovest), ma poiché c'è un muro in realtà fa una virata di 180 gradi e si sposta indietro verso est come se avesse raggiunto un vicolo cieco.
Di conseguenza, il seguente bit viene ora eseguito:
" No-op.
* Multiply two zeros on top of the stack, i.e. also a no-op.
The top of the stack is now still zero, so the IP keeps moving east.
@ Terminate the program.
C B A) Se è chiaramente specificato nella risposta?