Cubix, 94 83 82 79 63 56 byte
p>q'-?w.uh'e@U7.'hqi?oqB-!ul.-..$WWu_q<o'\;>....6t?.../!@
Mở rộng:
p > q '
- ? w .
u h ' e
@ U 7 .
' h q i ? o q B - ! u l . - . .
$ W W u _ q < o ' \ ; > . . . .
6 t ? . . . / ! @ . . . . . . .
. . . . . . . . . . . . . . . .
. . . .
. . . .
. . . .
. . . .
Ghi chú
- Trình thông dịch sẽ vô hiệu hóa trường đầu vào khi chương trình bắt đầu. Như vậy, một dòng đầu vào vô hạn là không thể. Chương trình này lấy từng ký tự đầu vào, vì vậy nếu không có giới hạn này, nó sẽ hoạt động bình thường.
- Chương trình này không dọn sạch ngăn xếp và nó trở nên lộn xộn rất nhanh. Vì máy này sẽ được sử dụng trên rõ ràng có thể cung cấp luồng đầu vào vô hạn, nên có vẻ hợp lý khi cho rằng nó cũng có bộ nhớ vô hạn.
- Bất kỳ và tất cả sự giúp đỡ chơi golf được nhiều đánh giá cao.
Dùng thử trực tuyến
Bạn có thể thử chương trình tại đây .
Giải trình
Ý tưởng chung
Ý tưởng chung là chúng tôi muốn đọc một ký tự, và sau đó kiểm tra nó với các ký tự khác nhau (đầu tiên h
, sau đó e
, sau đó, l
v.v.). Để theo dõi nhân vật mà chúng tôi đã bỏ lỡ, chúng tôi giữ nó ở dưới cùng của ngăn xếp. Khi chúng ta cần nó, chúng ta có thể dễ dàng đưa nó lên đỉnh một lần nữa.
Vòng lặp đọc / ghi
Vòng lặp đọc-ghi chỉ đơn giản là dòng thứ 5 . Tất cả các ký tự không được sử dụng được thay thế bằng no-ops ( .
):
. . . .
. . . .
. . . .
@ . . .
' h q i ? o q B - ! u l . - . .
. . . . _ . . . . . . . . . . .
. . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . .
. . . .
. . . .
. . . .
. . . .
Điều này có thể được chia thành hai phần: Đọc và (viết và kiểm tra). Phần đầu tiên chứa các hướng dẫn lên đến và bao gồm cả dấu hỏi. Phần thứ hai trở lên là phần còn lại của dòng. Vì vòng lặp này, chúng tôi giả sử chúng tôi bắt đầu với một chồng[...]
@
'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
Phần thứ hai (viết và kiểm tra) là tuyến tính một lần nữa. Các ngăn xếp bắt đầu như [next-char, ..., input]
. Chúng tôi trừu tượng hóa nhân vật tiếp theo, bởi vì điều đó thay đổi sau đó trong chương trình.
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.
Bây giờ, IP sẽ bắt đầu lại ở đầu vòng lặp này, đặt lại ký tự tiếp theo để kiểm tra h
.
Phù hợp với nhân vật tiếp theo
Nếu IP thực hiện lần lượt (nghĩa là ký tự chúng ta đọc và in khớp với ký tự tiếp theo 'hello'
), chúng ta cần kiểm tra ký tự đầu vào là gì và tùy thuộc vào đó, đẩy ký tự tiếp theo xuống dưới cùng của ngăn xếp. Sau đó, chúng ta cần quay lại vòng lặp đọc / ghi, mà không cần đẩy h
vào ngăn xếp, vì vậy chúng ta cần một cách khác để đến đó.
Điều đầu tiên trước tiên: xác định nhân vật đầu vào là gì. Các ngăn xếp trông như thế này : [..., prev-char, input, 0]
.
. . . .
- ? . .
u h ' e
. . . .
. . . . . . . . . ! u . . . . .
. . . . . . . . . \ ; . . . . .
. . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . .
. . . .
. . . .
. . . .
. . . .
Để so sánh đầu vào, chúng tôi sử dụng mã ký tự của h
một lần nữa. Ban đầu, điều này là do tôi không thực sự biết mình sẽ xử lý việc này như thế nào và h
là nhân vật đầu tiên trong chuỗi để kiểm tra, nhưng cuối cùng nó khá thuận tiện. Nếu chúng ta trừ mã ký tự của h khỏi đầu vào, chúng ta sẽ nhận được -3
nếu đầu vào là e
, 0
nếu đầu vào là h
, 4
nếu đầu vào là l
và7
nếu đầu vào là o
.
Điều này rất hữu ích, vì ?
lệnh cho phép chúng ta dễ dàng tách các giá trị âm khỏi giá trị dương và 0. Như vậy, nếu IP rẽ trái, sự khác biệt là âm, do đó, đầu vào là e
, vì vậy ký tự tiếp theo phải là một l
. Nếu IP tiếp tục đi thẳng, sự khác biệt là 0
, vì vậy đầu vào là h
, vì vậy ký tự tiếp theo sẽ là một e
. Nếu đầu vào là một l
hoặc một o
, IP rẽ phải.
Tất cả các hướng dẫn được thực hiện trước dấu chấm hỏi đã nói ở trên là:
;!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]
Bây giờ IP thay đổi hướng của nó như chi tiết ở trên. Chúng ta hãy đi qua các khả năng khác nhau.
Đầu vào 'e'
Trước tiên, chúng tôi sẽ xem xét đầu vào e
, khiến IP di chuyển lên trên ?
, vì sự khác biệt là 3. Tất cả các ký tự không liên quan đã bị xóa khỏi khối.
. > q '
. ? . .
. . . .
. . . .
. . q . . . . . . . . l . . . .
$ W W . . . . . . . . > . . . .
. . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . .
. . . .
. . . .
. . . .
. . . .
Các ký tự được thực hiện theo thứ tự này (không bao gồm một số ký tự điều khiển):
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, ...]
Bây giờ IP đã đạt đến vòng lặp đọc / ghi một lần nữa.
Đầu vào 'h'
Nếu đầu vào là 'h'
, chênh lệch là 0, do đó IP không thay đổi hướng của nó. Đây là khối lập phương một lần nữa, với tất cả các ký tự không liên quan được loại bỏ. Vì đường dẫn này bao gồm khá nhiều no-op, tất cả các no-op mà nó đi qua đã được thay thế bằng &
. IP bắt đầu ở dấu hỏi.
. . . .
. ? w .
. . ' e
. . . .
. . . . . . . . . ! . . . . . .
. . . u _ q < . . \ . . . . . .
. . ? & & & / . . & . . . . . .
. . & . . . . . . & . . . . . .
. . . .
& & & &
. . . .
. . . .
Các hướng dẫn được thực hiện là:
'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
Và bây giờ chúng ta lại bước vào vòng lặp đọc / ghi, vậy là xong.
Đầu vào khác
Tất cả các đầu vào khác dẫn đến một sự khác biệt tích cực, vì vậy IP quay đúng ở dấu hỏi. Chúng ta vẫn cần tách biệt l
và o
, vì vậy đó là những gì chúng ta sẽ làm tiếp theo.
Tách 'l'
và'o'
Hãy nhớ rằng sự khác biệt là 7 cho o
và 4 cho l
và chúng ta phải kết thúc chương trình nếu đầu vào là một o
. Đây là khối lập phương một lần nữa với các phần không liên quan được thay thế bằng a .
và các dấu chéo IP đã được thay thế bằng ký hiệu.
. . 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
Khác biệt giữa hai 'l'
s
Vì vậy, bây giờ chúng tôi biết rằng đầu vào là một l
, nhưng chúng tôi không biết cái nào l
. Nếu đó là lần đầu tiên, chúng ta cần đẩy người khác l
xuống dưới cùng của ngăn xếp, nhưng nếu đó là lần thứ hai, chúng ta cần phải đẩy một o
. Hãy nhớ rằng chúng tôi đã lưu -3
vào dưới cùng của ngăn xếp ngay trước khi chúng tôi đẩy đầu tiên l
? Chúng ta có thể sử dụng điều đó để tách hai nhánh.
. . . .
. . . .
. . . .
. . . .
. . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . .
6 t ? . . . . . . . . . . . . .
. . . . . . . . . . . . . . . .
. . . .
. . . .
. . . .
. . . .
Ngăn xếp bắt đầu như [..., -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
Đầu tiên 'l'
Nếu đây là lần đầu tiên 'l'
, chúng ta cần phải đẩy người khác 'l'
. Để lưu byte, chúng tôi sử dụng các ký tự giống như lần đầu tiên 'l'
. Chúng ta có thể đơn giản hóa ngăn xếp để [...]
. Đây là phần có liên quan của khối lập phương, không có thay thế bằng ký hiệu.
p > q '
. . . .
. . . .
. . . .
' . q . . . . . . . . l . . . .
$ W W . . . . . . . . > & & & &
. . ? . . . . . . . . . . . . .
. . . . . . . . . . . . . . . .
. . . .
. . . .
. . . .
. . . .
Các hướng dẫn sau đây được thực hiện:
$'pq'lq
$' no-op
pq no-op
'l Push the character code of l
Stack: [..., 108]
q Send it to the bottom
Stack: [108, ...]
Chúng tôi sắp bước vào vòng đọc / ghi, vì vậy chúng tôi đã hoàn thành với nhánh này.
Thứ hai 'l'
Nếu đầu vào là người thứ hai 'l'
trong 'hello'
, IP quay ngay tại dấu chấm hỏi. Một lần nữa, chúng ta có thể đơn giản hóa ngăn xếp [...]
và IP bắt đầu ?
, chỉ về phía nam lần này.
. . . .
. . . .
. . . .
. . . .
. . . . . . . . . . . . . . . .
. . . u _ q < o ' \ . . . . . .
. . ? . . . . . . & . . . . . .
. . & . . . . . . & . . . . . .
. . . .
& & & &
. . . .
. . . .
Các hướng dẫn được thực hiện là:
'oq_
'o Push the character code of 'o'
Stack: [..., 111]
q Move the top item to the bottom
Stack: [111, ...]
_ No-op
Và IP sắp sửa nhập lại vòng lặp đọc / ghi, vì vậy chúng tôi cũng đã hoàn thành với nhánh này.