Cubix, 94 83 82 79 63 56 byte
p>q'-?w.uh'e@U7.'hqi?oqB-!ul.-..$WWu_q<o'\;>....6t?.../!@
Diperluas:
p > q '
- ? w .
u h ' e
@ U 7 .
' h q i ? o q B - ! u l . - . .
$ W W u _ q < o ' \ ; > . . . .
6 t ? . . . / ! @ . . . . . . .
. . . . . . . . . . . . . . . .
. . . .
. . . .
. . . .
. . . .
Catatan
- Interpreter menonaktifkan kolom input saat program dimulai. Dengan demikian, aliran input yang tidak terbatas tidak mungkin. Program ini mengambil input karakter per karakter, jadi jika bukan karena batasan ini, itu akan berfungsi dengan baik.
- Program ini tidak membersihkan tumpukan, dan menjadi berantakan dengan sangat cepat. Karena mesin ini akan digunakan pada ternyata dapat memberikan aliran input yang tak terbatas, tampaknya masuk akal untuk menganggap bahwa ia juga memiliki memori yang tak terbatas.
- Bantuan golf apa saja sangat dihargai.
Cobalah online
Anda bisa mencoba programnya sini .
Penjelasan
Ide umum
Gagasan umum adalah bahwa kita ingin membaca sebuah karakter, dan kemudian memeriksanya terhadap berbagai karakter (pertama h
, lalu e
, kemudianl
dll). Untuk melacak karakter yang telah kita lewatkan, kita menyimpannya di bagian paling bawah tumpukan. Ketika kita membutuhkannya, kita dapat dengan mudah membawanya ke atas lagi.
Baca / Tulis loop
Loop baca-tulis hanyalah baris ke- 5 . Semua karakter yang tidak digunakan digantikan oleh no-ops ( .
):
. . . .
. . . .
. . . .
@ . . .
' h q i ? o q B - ! u l . - . .
. . . . _ . . . . . . . . . . .
. . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . .
. . . .
. . . .
. . . .
. . . .
Ini dapat dibagi menjadi dua bagian: Membaca dan (menulis dan memeriksa). Bagian pertama berisi instruksi hingga dan termasuk tanda tanya. Bagian kedua adalah sisa baris. Karena ini berulang, kita asumsikan kita mulai dengan setumpuk[...]
@
'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
Bagian kedua (menulis dan memeriksa) linier lagi. Tumpukan dimulai sebagai [next-char, ..., input]
. Kami mengabstraksi karakter berikutnya, karena itu berubah kemudian dalam program.
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.
Sekarang, IP akan mulai lagi pada awal loop ini, mengatur ulang karakter berikutnya untuk diperiksa h
.
Mencocokkan karakter berikutnya
Jika IP berbelok-u (yaitu karakter yang kita baca dan cetak cocok dengan karakter berikutnya 'hello'
), kita perlu memeriksa karakter apa yang dimasukkan dan tergantung pada itu, dorong karakter berikutnya ke bagian bawah tumpukan. Setelah itu, kita perlu kembali ke loop baca / tulis, tanpa mendorong h
ke stack, jadi kita perlu cara lain untuk sampai ke sana.
Hal pertama yang pertama: menentukan karakter apa yang dimasukkan. Tumpukan terlihat seperti ini: [..., prev-char, input, 0]
.
. . . .
- ? . .
u h ' e
. . . .
. . . . . . . . . ! u . . . . .
. . . . . . . . . \ ; . . . . .
. . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . .
. . . .
. . . .
. . . .
. . . .
Untuk membandingkan input, kami menggunakan kode karakter h
lagi. Awalnya, ini karena saya tidak benar-benar tahu bagaimana saya akan menangani ini dan h
merupakan karakter pertama dalam string yang diperiksa, tetapi akhirnya menjadi cukup nyaman. Jika kita mengurangi kode karakter h dari input, kita dapatkan -3
jika inputnya adalah e
, 0
jika inputnya adalah h
, 4
jika inputnya adalah l
dan 7
jika inputnya adalaho
.
Ini berguna, karena ?
perintah tersebut memungkinkan kita dengan mudah memisahkan nilai negatif dari nilai positif dan nol. Dengan demikian, jika IP belok kiri, perbedaannya negatif, jadi inputnya adalah e
, jadi karakter selanjutnya harus menjadi l
. Jika IP terus berjalan lurus, perbedaannya adalah 0
, jadi inputnya adalah h
, jadi karakter selanjutnya harus menjadi e
. Jika inputnya adalah an l
atau an o
, IP berbelok ke kanan.
Semua instruksi yang dijalankan sebelum tanda tanya tersebut adalah:
;!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]
Sekarang IP mengubah arahnya seperti yang dijelaskan di atas. Mari kita membahas berbagai kemungkinan yang berbeda.
Memasukkan 'e'
Pertama kita akan mempertimbangkan input e
, yang menyebabkan IP bergerak ke atas dari ?
, karena perbedaannya adalah 3. Semua karakter yang tidak relevan telah dihapus dari kubus.
. > q '
. ? . .
. . . .
. . . .
. . q . . . . . . . . l . . . .
$ W W . . . . . . . . > . . . .
. . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . .
. . . .
. . . .
. . . .
. . . .
Karakter dieksekusi dalam urutan ini (tidak termasuk beberapa karakter aliran kontrol):
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, ...]
Sekarang IP telah mencapai loop baca / tulis lagi.
Memasukkan 'h'
Jika inputnya adalah 'h'
, selisihnya adalah 0, sehingga IP tidak mengubah arahnya. Inilah kubusnya lagi, dengan semua karakter yang tidak relevan dihapus. Karena jalur ini mencakup beberapa no-ops, semua no-ops yang dilaluinya telah diganti oleh &
. IP dimulai pada tanda tanya.
. . . .
. ? w .
. . ' e
. . . .
. . . . . . . . . ! . . . . . .
. . . u _ q < . . \ . . . . . .
. . ? & & & / . . & . . . . . .
. . & . . . . . . & . . . . . .
. . . .
& & & &
. . . .
. . . .
Instruksi yang dijalankan adalah:
'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
Dan sekarang kita memasuki loop baca / tulis lagi, jadi kita selesai.
Masukan lainnya
Semua input lainnya menghasilkan perbedaan positif, sehingga IP berbelok ke kanan pada tanda tanya. Kita masih perlu memisahkan l
dano
, jadi itulah yang akan kita lakukan selanjutnya.
Memisahkan 'l'
dan'o'
Perlu diingat bahwa perbedaannya adalah 7 untuk o
dan 4 untuk l
dan bahwa kita harus mengakhiri program jika inputnya adalah o
. Inilah kubus lagi dengan bagian-bagian yang tidak relevan digantikan oleh a .
dan no-ops IP crosses telah digantikan oleh ampersand.
. . 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
Membedakan antara dua 'l'
s
Jadi, sekarang kita sudah tahu inputnya adalah l
, tetapi kita tidak tahu yang mana l
. Jika ini yang pertama, kita perlu mendorong yang lain l
ke bagian bawah tumpukan, tetapi jika yang kedua, kita perlu mendorong o
. Ingat kami menyimpan -3
ke bagian bawah tumpukan tepat sebelum kami mendorong yang pertama l
? Kita dapat menggunakannya untuk memisahkan dua cabang.
. . . .
. . . .
. . . .
. . . .
. . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . .
6 t ? . . . . . . . . . . . . .
. . . . . . . . . . . . . . . .
. . . .
. . . .
. . . .
. . . .
Tumpukan dimulai sebagai [..., -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
Pertama 'l'
Jika ini yang pertama 'l'
, kita perlu mendorong yang lain 'l'
. Untuk menyimpan byte, kami menggunakan karakter yang sama dengan yang pertama 'l'
. Kami dapat menyederhanakan tumpukan menjadi[...]
. Inilah bagian yang relevan dari kubus, dengan no-op digantikan oleh ampersand.
p > q '
. . . .
. . . .
. . . .
' . q . . . . . . . . l . . . .
$ W W . . . . . . . . > & & & &
. . ? . . . . . . . . . . . . .
. . . . . . . . . . . . . . . .
. . . .
. . . .
. . . .
. . . .
Instruksi berikut dijalankan:
$'pq'lq
$' no-op
pq no-op
'l Push the character code of l
Stack: [..., 108]
q Send it to the bottom
Stack: [108, ...]
Kami akan memasuki loop baca / tulis, jadi kami selesai dengan cabang ini.
Kedua 'l'
Jika input adalah yang kedua 'l'
dalam 'hello'
, IP berbelok ke kanan di tanda tanya. Sekali lagi, kita dapat menyederhanakan tumpukan [...]
dan IP mulai ?
, menunjuk ke selatan saat ini.
. . . .
. . . .
. . . .
. . . .
. . . . . . . . . . . . . . . .
. . . u _ q < o ' \ . . . . . .
. . ? . . . . . . & . . . . . .
. . & . . . . . . & . . . . . .
. . . .
& & & &
. . . .
. . . .
Instruksi yang dijalankan adalah:
'oq_
'o Push the character code of 'o'
Stack: [..., 111]
q Move the top item to the bottom
Stack: [111, ...]
_ No-op
Dan IP akan memasuki loop baca / tulis lagi, jadi kita sudah selesai dengan cabang ini juga.