Cubix, 94 83 82 79 63 56 байт
p>q'-?w.uh'e@U7.'hqi?oqB-!ul.-..$WWu_q<o'\;>....6t?.../!@
Expanded:
p > q '
- ? w .
u h ' e
@ U 7 .
' h q i ? o q B - ! u l . - . .
$ W W u _ q < o ' \ ; > . . . .
6 t ? . . . / ! @ . . . . . . .
. . . . . . . . . . . . . . . .
. . . .
. . . .
. . . .
. . . .
Заметки
- Интерпретатор отключает поле ввода при запуске программы. Таким образом, бесконечный поток ввода невозможен. Эта программа принимает ввод за символом, поэтому, если бы не это ограничение, оно работало бы правильно.
- Эта программа не очищает стек, и она очень быстро запутывается. Поскольку машина, на которой это будет использоваться, по-видимому, может давать бесконечные входные потоки, разумно предположить, что она также имеет бесконечную память.
- Любая помощь в гольф очень ценится.
Попробуйте онлайн
Вы можете попробовать программу здесь .
объяснение
Главная идея
Общая идея заключается в том, что мы хотим прочитать символ, а затем проверить его на предмет изменяющихся символов (сначала h, затем e, затем lи т. Д.). Чтобы отслеживать пропущенного персонажа, мы держим его в самом низу стека. Когда нам это нужно, мы легко можем снова поднять его на вершину.
Цикл чтения / записи
Цикл чтения-записи - это просто 5- я строка. Все неиспользуемые символы заменяются на no-ops ( .):
. . . .
. . . .
. . . .
@ . . .
' h q i ? o q B - ! u l . - . .
. . . . _ . . . . . . . . . . .
. . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . .
. . . .
. . . .
. . . .
. . . .
Это можно разделить на две части: чтение и (написание и проверка). Первая часть содержит инструкции вплоть до знака вопроса. Вторая часть - это остальная часть строки. Поскольку это зацикливается, мы предполагаем, что мы начинаем со стека[...]
@
'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
Вторая часть (написание и проверка) снова линейна. Стек начинается как [next-char, ..., input]. Мы абстрагировали следующий символ, потому что это меняется позже в программе.
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.
Теперь, IP начнется снова в начале этого цикла, сбрасывая следующий символ для проверки h.
Соответствие следующему персонажу
Если IP сделал разворот (т. Е. Символ, который мы прочитали и напечатали, соответствовал следующему символу 'hello'), нам нужно проверить, каким символом был ввод, и в зависимости от этого сдвинуть следующий символ в конец стека. После этого нам нужно вернуться к циклу чтения / записи, не помещая hего в стек, поэтому нам нужен другой способ попасть туда.
Перво-наперво: определите, каким персонажем был ввод. Стек выглядит следующим образом : [..., prev-char, input, 0].
. . . .
- ? . .
u h ' e
. . . .
. . . . . . . . . ! u . . . . .
. . . . . . . . . \ ; . . . . .
. . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . .
. . . .
. . . .
. . . .
. . . .
Чтобы сравнить ввод, мы hснова используем код символа . Первоначально это было потому, что я не знал, как я собираюсь с этим справиться, и hэто первый символ в строке, который нужно проверить, но в итоге это оказалось довольно удобным. Если мы вычтем код символа h из ввода, мы получим, -3если вход есть e, 0если вход есть h, 4если вход lи 7если вход o.
Это полезно, потому что ?команда позволяет нам легко отделить отрицательные значения от положительных значений и нуля. Таким образом, если IP поворачивается влево, разница была отрицательной, поэтому ввод был e, поэтому следующий символ должен быть l. Если IP продолжает идти прямо, разница была 0, поэтому ввод был h, поэтому следующий символ должен быть e. Если вход является lили o, IP поворачивается направо.
Все инструкции, выполненные до вышеупомянутого знака вопроса:
;!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]
Теперь IP меняет свое направление, как описано выше. Давайте рассмотрим различные возможности.
вход 'e'
Сначала мы рассмотрим ввод e, который заставляет IP двигаться вверх от ?, так как разница равна 3. Все нерелевантные символы были удалены из куба.
. > q '
. ? . .
. . . .
. . . .
. . q . . . . . . . . l . . . .
$ W W . . . . . . . . > . . . .
. . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . .
. . . .
. . . .
. . . .
. . . .
Символы выполняются в следующем порядке (исключая некоторые символы потока управления):
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, ...]
Теперь IP снова достиг цикла чтения / записи.
вход 'h'
Если вход был 'h', разница равна 0, поэтому IP не меняет своего направления. Снова куб, со всеми не относящимися к делу персонажами. Поскольку этот путь включает в себя довольно много неактивных операций, все пропущенные им операции были заменены &. IP начинается с вопросительного знака.
. . . .
. ? w .
. . ' e
. . . .
. . . . . . . . . ! . . . . . .
. . . u _ q < . . \ . . . . . .
. . ? & & & / . . & . . . . . .
. . & . . . . . . & . . . . . .
. . . .
& & & &
. . . .
. . . .
Выполненные инструкции:
'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
И теперь мы снова входим в цикл чтения / записи, так что мы закончили.
Другие входы
Все остальные входные данные приводят к положительной разнице, поэтому IP-адрес поворачивается направо на вопросительный знак. Нам все еще нужно разделить lи oто, что мы будем делать дальше.
Разделение 'l'и'o'
Имейте в виду, что разница составляет 7 для oи 4 для lи что мы должны завершить программу, если ввод был o. Вот куб снова с нерелевантными частями, замененными на a, .и нет-опы, кресты IP были заменены амперсандами.
. . 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
Различение между этими двумя 'l'с
Итак, теперь мы знаем, что вклад был l, но мы не знаем, какой l. Если это первое, нам нужно подтолкнуть другого lк нижней части стека, но если это второе, нам нужно подтолкнуть o. Помните, мы сохранили -3в конец стека как раз перед тем, как выдвинуть первый l? Мы можем использовать это для разделения двух ветвей.
. . . .
. . . .
. . . .
. . . .
. . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . .
6 t ? . . . . . . . . . . . . .
. . . . . . . . . . . . . . . .
. . . .
. . . .
. . . .
. . . .
Стек начинается как [..., -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
Первый 'l'
Если это было первым 'l', нам нужно подтолкнуть другого 'l'. Для сохранения байтов мы используем те же символы, что и для первого 'l'. Мы можем упростить стек до [...]. Вот соответствующая часть куба, где нет операций, замененных амперсандами.
p > q '
. . . .
. . . .
. . . .
' . q . . . . . . . . l . . . .
$ W W . . . . . . . . > & & & &
. . ? . . . . . . . . . . . . .
. . . . . . . . . . . . . . . .
. . . .
. . . .
. . . .
. . . .
Следующие инструкции выполняются:
$'pq'lq
$' no-op
pq no-op
'l Push the character code of l
Stack: [..., 108]
q Send it to the bottom
Stack: [108, ...]
Мы собираемся войти в цикл чтения / записи, поэтому мы закончили с этой веткой.
второй 'l'
Если вход был вторым 'l'в 'hello', то IP повернул направо на знак вопроса. Еще раз, мы можем упростить стек, [...]и IP начинается с, на ?этот раз, указывая на юг.
. . . .
. . . .
. . . .
. . . .
. . . . . . . . . . . . . . . .
. . . u _ q < o ' \ . . . . . .
. . ? . . . . . . & . . . . . .
. . & . . . . . . & . . . . . .
. . . .
& & & &
. . . .
. . . .
Выполненные инструкции:
'oq_
'o Push the character code of 'o'
Stack: [..., 111]
q Move the top item to the bottom
Stack: [111, ...]
_ No-op
И IP собирается снова войти в цикл чтения / записи, так что мы закончили и с этой веткой.