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 lecc.). 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 hnello 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 hnuovamente 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 -3se l'input è e, 0se l'input è h, 4se l'input è le 7se 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 lo 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 le il o, quindi è quello che faremo dopo.
Separare il 'l'e'o'
Tieni presente che la differenza è 7 per oe 4 per le 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 lin fondo alla pila, ma se è il secondo, dobbiamo spingere un o. Ricordi che abbiamo salvato -3in 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.