:?
:
#/)
\ #
!"*@
"
Попробуйте онлайн!
Это выводит результаты в порядке, C, B, A
разделенном переводом строки.
объяснение
Как обычно, короткий лабиринтный праймер:
- Лабиринт имеет два набора целых чисел произвольной точности, main и aux (ily), которые изначально заполнены (неявным) бесконечным количеством нулей. Мы будем использовать только основной для этого ответа.
- Исходный код напоминает лабиринт, где указатель инструкций (IP) следует за коридорами, когда это возможно (даже за углами). Код начинается с первого действительного символа в порядке чтения, то есть в этом случае в верхнем левом углу. Когда IP-адрес достигает какой-либо формы соединения (т. Е. Нескольких соседних ячеек в дополнение к той, из которой он получен), он выбирает направление на основе вершины основного стека. Основные правила: поверните налево при отрицательном значении, продолжайте движение вперед при нулевом, поверните направо при положительном. И когда один из них невозможен из-за наличия стены, тогда IP будет идти в противоположном направлении. IP также оборачивается при попадании в тупик.
Несмотря на два no-ops ( "
), которые делают макет немного расточительным, я вполне доволен этим решением, потому что поток управления на самом деле довольно тонкий.
IP начинается в верхнем левом углу :
справа. Он сразу же попадет в тупик ?
и развернется, так что программа фактически запустится с этим линейным фрагментом кода:
: Duplicate top of main stack. This will duplicate one of the implicit zeros
at the bottom. While this may seem like a no-op it actually increases
the stack depth to 1, because the duplicated zero is *explicit*.
? Read n and push it onto main.
: Duplicate.
: Duplicate.
Это означает, что у нас теперь есть три копии n
в главном стеке, но его глубина равна 4
. Это удобно, потому что это означает, что мы можем получить глубину стека, чтобы извлечь текущий множитель при работе с копиями ввода.
IP теперь входит в (по часовой стрелке) цикл 3х3. Обратите внимание, что #
, увеличивая глубину стека, мы всегда получим положительное значение, так что мы знаем, что IP будет всегда поворачиваться на восток в этой точке.
Тело цикла выглядит так:
# Push the stack depth, i.e. the current multiplier k.
/ Compute n / k (rounding down).
) Increment.
# Push the stack depth again (this is still k).
* Multiply. So we've now computed (n/k+1)*k, which is the number
we're looking for. Note that this number is always positive so
we're guaranteed that the IP turns west to continue the loop.
" No-op.
! Print result. If we've still got copies of n left, the top of the
stack is positive, so the IP turns north and does another round.
Otherwise, see below...
\ Print a linefeed.
Then we enter the next loop iteration.
После того, как цикл был пройден (до !
) три раза, все копии n
израсходованы и ноль внизу обнаружен. Из- "
за нижней части (которая в противном случае кажется довольно бесполезной) эта позиция является перекрестком. Это означает, что с нулем на вершине стека IP пытается идти прямо вперед (на запад), но, поскольку есть стена, он на самом деле делает поворот на 180 градусов и движется обратно на восток, как если бы он зашел в тупик.
В результате теперь выполняется следующий бит:
" No-op.
* Multiply two zeros on top of the stack, i.e. also a no-op.
The top of the stack is now still zero, so the IP keeps moving east.
@ Terminate the program.
C B A
), если это четко указано в ответе?