迷宫,19字节
:?
:
#/)
\ #
!"*@
"
在线尝试!
这将以C, B, A
换行符分隔的顺序输出结果。
说明
与往常一样,简短的迷宫底漆:
- 迷宫有两堆任意精度的整数,分别是main和aux(iliary),它们最初都填充了(隐式)无限数量的零。我们只会将main用于此答案。
- 源代码类似于一个迷宫,在该迷宫中,指令指针(IP)可以(甚至在拐角处)跟随走廊。代码从阅读顺序的第一个有效字符开始,即在这种情况下从左上角开始。当IP到达任何形式的联结时(即,除了它来自的单元之外,还有几个相邻的单元),它将根据主堆栈的顶部选择一个方向。基本规则是:负数时左转,零时继续前进,正数时右转。如果由于存在隔离墙而无法实现其中之一,那么IP将采取相反的方向。当遇到死胡同时,IP也将转过来。
尽管有两次无操作("
)使得布局看起来有些浪费,但是我对这种解决方案感到非常满意,因为它的控制流程实际上非常微妙。
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
在主堆栈上有3个副本,但其深度为4
。这很方便,因为这意味着我们可以在处理输入的副本时,通过堆栈深度来检索当前的乘数。
IP现在进入(顺时针)3x3循环。请注意#
,它推动堆栈深度,它将始终推动一个正值,这样我们就知道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.
遍历循环(最多!
)3次后,的所有副本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
如果答案中明确指定了结果,我们可以(一致地)以不同的顺序(例如)输出结果吗?