迷宫,40字节
<
,,}:?
.
;(" {(={}{".
,",;=};} }) "{@
输入N
后跟字符串,用任何非数字字符分隔。
在线尝试!
这是与Sp3000协作编写的(这意味着我不必费心找出一个算法,因此他开始研究它,提出了118字节的解决方案,但是不费力打高尔夫球,所以我就打了高尔夫球。 ..对团队合作而言。
说明
Sp的常用底漆(通常稍加修改):
- 迷宫是一种基于堆栈的2D语言,具有两个堆栈,主堆栈和辅助堆栈。几乎所有事情都发生在主堆栈上,但是您可以将值转移到另一个堆栈上,例如反转它们或将它们保存以备后用。
- 堆栈是无底的,并填充有零,因此从空堆栈弹出不会出错。
- 从第一个有效字符(此处为左上角)开始执行。在每个结点,有两条或更多条可能的指令指针(IP)可以采用的路径,将检查堆栈的顶部以确定下一步要走的地方。负向左转,零向前进,正向右转。虽然这样做的目的是使代码看起来像蜿蜒曲折的段落,但没有什么能阻止您创建“房间”,在每个房间检查这些条件。这些可能会产生不可预测的行为,但非常适合打高尔夫球。
- 可以在运行时修改源代码(以及迷宫的布局),使用
<>^v
该代码周期性地移动行或列或网格。
"
没有人。
开始了。
该代码以开头<
,这是我从一长串线性代码开始使用几次的高尔夫技巧。它将第一行循环左移,并带有IP,因此源看起来像这样:
<
,,}:?
.
;(" {(={}{".
,",;=};} }) "{@
但是现在IP无法移动到任何地方,因此它将<
再次执行。这一直持续到我们达到以下状态:
<
,,}:?
.
;(" {(={}{".
,",;=};} }) "{@
此时,IP可以离开单元并开始执行从开始的第二行?
。所以这是分解的线性代码:
? # Read the first integer on STDIN, i.e. N.
:} # Duplicate it and move one copy over to the auxiliary stack.
, # Read the separator character.
,. # Read the first character of the input string and directly print it.
IP现在进入3x2机房,实际上是两个紧密压缩(重叠)的2x2顺时针循环。第一个循环N-1
从STDIN 读取并丢弃字符。
; # Discard the top of the stack. On the first iteration, this is the
# separator we've already read. On subsequent iterations this will be
# one of the N-1 characters from the input string.
( # Decrement N. If this hits zero, we leave the loop, otherwise we continue.
, # Read the next character from STDIN to be discarded.
现在我们进入第二个循环,该循环读取输入字符串的其余部分。我们可以检测到EOF,因为在这种情况下,
它将返回-1
,从而使IP左转。
, # Read a character. Exit the loop if EOF.
( # Decrement it.
这个减量实际上并没有用,但是我们以后可以免费撤销它,这里它允许我们将两个循环重叠。
如果以5 ABCDEFGHIJKLMNOP
输入为例,则堆栈如下所示:
Main [ ... 'E' 'F' 'G' 'H' 'I' 'J' 'K' 'L' 'M' 'N' 'O' -1 | 5 ... ] Auxiliary
请注意,这些实际上对应于输入字符FGHIJKLMNOP
(因为我们将它们减少了),并且实际上我们不想打印其中的第一个N-1
字符(我们只丢弃了字符,但想跳过N
)。
现在有一个简短的线性位,可以为下一个循环准备堆栈:
; # Discard the -1.
= # Swap the tops of the stacks, i.e. N with the last character.
# By putting the last character on the auxiliary stack, we ensure that
# it doesn't get discarded in the next loop.
} # Move N over to the auxiliary stack as well.
堆栈现在看起来像:
Main [ ... 'E' 'F' 'G' 'H' 'I' 'J' 'K' 'L' 'M' 'N' | 5 'O' ... ] Auxiliary
我们进入另一个2x2顺时针循环。这会丢弃N
主堆栈中的前几个字符:
; # Discard the top of the main stack.
{ # Pull N over from the auxiliary stack.
( # Decrement it. It it's 0 we leave the loop.
} # Push N back to the auxiliary stack.
当我们退出循环时=
,它会0
再次与输入字符串的最后一个字符交换。现在堆栈看起来像这样:
Main [ ... 'E' 'F' 'G' 'H' 'I' 'O' | ... ] Auxiliary
我们要从左侧开始打印主堆栈的内容(底部元素除外,所有元素都加1)。这意味着我们需要将其移至辅助堆栈。这就是下一个2x2(顺时针)循环的作用:
{ # Pull an element over from the auxiliary stack. This is necessary so we
# have a 0 on top of the stack when entering the loop, to prevent the IP
# from turning right immediately.
} # Move the top of the main stack back to the auxiliary stack. If this was the
# bottom of the stack, exit the loop.
) # Increment the current character.
} # Move it over to the auxiliary stack.
现在堆叠:
Main [ ... | 'F' 'G' 'H' 'I' 'J' 'P] ... ] Auxiliary
我们使用将第一个(我们不想打印的)移回主堆栈{
。现在,我们进入最后的2x2(逆时针)循环,该循环将打印其余部分:
{ # Pull another character over from the auxiliary stack. Exit the loop
# if that's the zero at the bottom of the stack.
. # Print the character.
最后,我们使用终止程序@
。
'
用作计数字符之类的一元数吗?例如:''123321
?