Cubix, 94 83 82 79 63 56 byte
p>q'-?w.uh'e@U7.'hqi?oqB-!ul.-..$WWu_q<o'\;>....6t?.../!@
Allargato:
p > q '
- ? w .
u h ' e
@ U 7 .
' h q i ? o q B - ! u l . - . .
$ W W u _ q < o ' \ ; > . . . .
6 t ? . . . / ! @ . . . . . . .
. . . . . . . . . . . . . . . .
. . . .
. . . .
. . . .
. . . .
Gli appunti
- L'interprete disabilita il campo di input all'avvio del programma. Pertanto, un flusso infinito di input è impossibile. Questo programma accetta l'input carattere per carattere, quindi se non fosse per questa limitazione, funzionerebbe correttamente.
- Questo programma non cancella lo stack e diventa molto disordinato. Dal momento che la macchina su cui apparentemente sarà in grado di fornire flussi di input infiniti, sembra ragionevole supporre che abbia anche una memoria infinita.
- Qualsiasi aiuto sul golf è molto apprezzato.
Provalo online
Puoi provare il programma qui .
Spiegazione
Idea generale
L'idea generale è che vogliamo leggere un personaggio e quindi confrontarlo con vari personaggi (prima h
, poi e
, poi l
ecc.). Per tenere traccia del personaggio che abbiamo perso, lo teniamo in fondo alla pila. Quando ne abbiamo bisogno, possiamo facilmente riportarlo in cima.
Ciclo di lettura / scrittura
Il ciclo di lettura-scrittura è semplicemente la quinta riga. Tutti i caratteri non utilizzati vengono sostituiti da no-ops ( .
):
. . . .
. . . .
. . . .
@ . . .
' h q i ? o q B - ! u l . - . .
. . . . _ . . . . . . . . . . .
. . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . .
. . . .
. . . .
. . . .
. . . .
Questo può essere suddiviso in due parti: lettura e (scrittura e controllo). La prima parte contiene le istruzioni fino al punto di domanda incluso. La seconda parte è il resto della linea. Dato che questo circola in giro, supponiamo di iniziare con una pila di[...]
@
'hqi?
_
Explanation
'h Push the character code of the h
Stack: [..., 104]
q Send it to the bottom
Stack: [104, ...]
i Read one character of the input (-1 for EOF)
Stack: [104, ..., input]
? Start of condition:
if (input < 0):
@ execute '@', ending the program
if (input = 0):
continue going right
if (input > 0):
_ turn to the right, reflect back ('_') and
turn right again, effectively not changing
the direction at all
La seconda parte (scrittura e controllo) è di nuovo lineare. Lo stack inizia come [next-char, ..., input]
. Abbiamo estratto il personaggio successivo, perché questo cambia più avanti nel programma.
oqB-!ul.- Explanation
o Output the character at the top of the stack
q Send the input to the bottom of the stack
Stack: [input, next-char, ...]
B Reverse the stack
Stack: [..., next-char, input]
- Push the difference of the top two characters, which
is 0 if both are equal, something else otherwise
Stack: [..., next-char, input, diff]
! if (diff = 0):
u make a u-turn to the right
else:
l. execute two no-ops
- push [input - next-char - input], which is disregarded
later, so it effectively is a no-op as well.
Ora, l'IP ricomincerà all'inizio di questo ciclo, ripristinando il carattere successivo da controllare h
.
Abbinando il personaggio successivo
Se l'IP ha effettuato un'inversione di marcia (ovvero il carattere che abbiamo letto e stampato corrisponde al carattere successivo 'hello'
), dobbiamo controllare quale carattere era l'input e, a seconda di ciò, spingere il carattere successivo in fondo alla pila. Dopodiché, dobbiamo tornare al ciclo di lettura / scrittura, senza spingere h
nello stack, quindi abbiamo bisogno di un altro modo per arrivarci.
Per prima cosa: determinare quale carattere era l'input. Lo stack è simile al seguente: [..., prev-char, input, 0]
.
. . . .
- ? . .
u h ' e
. . . .
. . . . . . . . . ! u . . . . .
. . . . . . . . . \ ; . . . . .
. . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . .
. . . .
. . . .
. . . .
. . . .
Per confrontare l'input, utilizziamo h
nuovamente il codice carattere . Inizialmente, questo perché non sapevo davvero come avrei gestito questo ed h
è il primo personaggio della stringa da controllare, ma alla fine è stato abbastanza conveniente. Se sottraggiamo il codice carattere di h dall'input, otteniamo -3
se l'input è e
, 0
se l'input è h
, 4
se l'input è l
e 7
se l'input è o
.
Questo è utile, perché il ?
comando ci consente di separare facilmente i valori negativi da valori positivi e zero. Pertanto, se l'IP gira a sinistra, la differenza era negativa, quindi l'input era e
, quindi il carattere successivo dovrebbe essere un l
. Se l'IP continua ad andare dritto, la differenza era 0
, quindi l'input era h
, quindi il carattere successivo dovrebbe essere un e
. Se l'ingresso è un l
o un o
, l'IP gira a destra.
Tutte le istruzioni eseguite prima del punto interrogativo sopra menzionato sono:
;!e'h- Explanation
; Delete the top of the stack
Stack: [..., prev-char, input]
! if (input = 0):
e execute 'e' (no-op)
'h Push the character code of h
Stack: [..., prev-char, input, 104]
- Push the difference of the input and 104
Stack: [..., prev-char, input, 104, diff]
Ora l'IP cambia direzione come descritto sopra. Esaminiamo le diverse possibilità.
Ingresso 'e'
Per prima cosa considereremo l'input e
, che fa spostare l'IP verso l'alto dal ?
, poiché la differenza è 3. Tutti i caratteri irrilevanti sono stati rimossi dal cubo.
. > q '
. ? . .
. . . .
. . . .
. . q . . . . . . . . l . . . .
$ W W . . . . . . . . > . . . .
. . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . .
. . . .
. . . .
. . . .
. . . .
I caratteri vengono eseguiti in questo ordine (esclusi alcuni caratteri del flusso di controllo):
q'l$WWq
q Save the difference (-3) to the bottom of the stack so
we can tell whether the l on the bottom of the stack is
the first or the second l in hello
Stack: [-3, ...]
'l Push the character code of l to the stack
Stack: [-3, ..., 108]
$W no-op
W Sidestep into the loop
q Send the character code to the bottom
Stack: [108, -3, ...]
Ora l'IP ha raggiunto nuovamente il ciclo di lettura / scrittura.
Ingresso 'h'
Se l'ingresso era 'h'
, la differenza è 0, quindi l'IP non cambia direzione. Ecco di nuovo il cubo, con tutti i personaggi irrilevanti rimossi. Poiché questo percorso include alcune no-op, tutte le no-op che passa sono state sostituite &
. L'IP inizia dal punto interrogativo.
. . . .
. ? w .
. . ' e
. . . .
. . . . . . . . . ! . . . . . .
. . . u _ q < . . \ . . . . . .
. . ? & & & / . . & . . . . . .
. . & . . . . . . & . . . . . .
. . . .
& & & &
. . . .
. . . .
Le istruzioni eseguite sono:
'e!\?q_
'e Push the character code of the e
Stack: [..., 101]
! if (101 = 0):
\ reflect away (effectively a no-op)
? if (101 > 0):
turn right (always happens)
q Move 101 to the bottom of the stack
Stack: [101, ...]
_ No-op
E ora stiamo entrando di nuovo nel ciclo di lettura / scrittura, quindi abbiamo finito.
Altri input
Tutti gli altri input producono una differenza positiva, quindi l'IP gira a destra al punto interrogativo. Dobbiamo ancora separare il l
e il o
, quindi è quello che faremo dopo.
Separare il 'l'
e'o'
Tieni presente che la differenza è 7 per o
e 4 per l
e che dobbiamo terminare il programma se l'ingresso era un o
. Ecco di nuovo il cubo con le parti irrilevanti sostituite da una .
e le no-op che l'IP attraversa sono state sostituite da e commerciali.
. . q .
. ? w .
. h ' .
. U 7 .
. . . . . . . . . . . . . - . .
. . . . . . . . . . . . . & . .
. . . . . . / ! @ . . . . & . .
. . . . . . & . . . . . . & . .
. . & .
. . & .
. . & .
. . & .
h7'wq-!@
h no-op
7 Push 7 to the stack
Stack: [..., diff, 7]
'wq Push w to the stack and send it to
the bottom. We don't care about it,
so it's now part of the ellipsis.
Stack: [..., diff, 7]
-! if (diff = 7):
@ End the program
Discernere tra i due 'l'
s
Quindi, ora sappiamo che l'input è stato un l
, ma non sappiamo quale l
. Se è il primo, dobbiamo spingerne un altro l
in fondo alla pila, ma se è il secondo, dobbiamo spingere un o
. Ricordi che abbiamo salvato -3
in fondo alla pila appena prima di spingere il primo l
? Possiamo usarlo per separare i due rami.
. . . .
. . . .
. . . .
. . . .
. . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . .
6 t ? . . . . . . . . . . . . .
. . . . . . . . . . . . . . . .
. . . .
. . . .
. . . .
. . . .
Lo stack inizia come [..., -3 or 140, ...]
Explanation
6t?
6t Take the 6th item from the top and move
it to the top (which is either -3 or 140)
? If that's positive, turn right, otherwise,
turn left
Primo 'l'
Se questo è stato il primo 'l'
, dobbiamo spingerne un altro 'l'
. Per salvare i byte, utilizziamo gli stessi caratteri del primo 'l'
. Possiamo semplificare lo stack a [...]
. Ecco la parte rilevante del cubo, senza operazioni di sostituzione sostituite da e commerciali.
p > q '
. . . .
. . . .
. . . .
' . q . . . . . . . . l . . . .
$ W W . . . . . . . . > & & & &
. . ? . . . . . . . . . . . . .
. . . . . . . . . . . . . . . .
. . . .
. . . .
. . . .
. . . .
Vengono eseguite le seguenti istruzioni:
$'pq'lq
$' no-op
pq no-op
'l Push the character code of l
Stack: [..., 108]
q Send it to the bottom
Stack: [108, ...]
Stiamo per entrare nel ciclo di lettura / scrittura, quindi abbiamo finito con questo ramo.
Secondo 'l'
Se l'ingresso era il secondo 'l'
in 'hello'
, l'IP girava a destra al punto interrogativo. Ancora una volta, possiamo semplificare lo stack [...]
e l'IP inizia a ?
, puntando verso sud questa volta.
. . . .
. . . .
. . . .
. . . .
. . . . . . . . . . . . . . . .
. . . u _ q < o ' \ . . . . . .
. . ? . . . . . . & . . . . . .
. . & . . . . . . & . . . . . .
. . . .
& & & &
. . . .
. . . .
Le istruzioni eseguite sono:
'oq_
'o Push the character code of 'o'
Stack: [..., 111]
q Move the top item to the bottom
Stack: [111, ...]
_ No-op
E l'IP sta per entrare di nuovo nel ciclo di lettura / scrittura, quindi abbiamo finito anche con questo ramo.