:?
:
#/)
\ #
!"*@
"
Попробуйте онлайн!
Это выводит результаты в порядке, 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), если это четко указано в ответе?