Brainfuck,579字节
,[<<+>>>>+<<[[<+>>+<-]++++++[>-------<-]>-[-[-[-[--------------[--[<+++++[>-----
-<-]>+[--[<<[-]>>-]]<]>[>>-<<<<<[-]<[<]<<<[<]>>>>>>>>[<]<-[+>]+[->+]>>>>+>[<-]<[
>+<-<]>]<]>[<<<[-]-[<]>>>>>>>>>>>[<]<<<<<<[<]<-[+>]+[-<+]<<<+<[>-<<<]>[-<+<]]]<]
>[+>[-<]<[<<]<[-]>>]]<]+>[-[<-]<[>+>+<<-<]<[-]>+>]<<[>-]>[,>]<]<+<[>]>[>>>[<<<<[
-<]<<<]>>>+>>>>[<<<<->>>>[>>>[-<]>>>>]]]>[<<<[<+[-->>]]>[-[.[-]]]>[<]>[<<++++++[
>+++++++<-]>+>>[<<.>>-]<<++>-[<.>-]+++[<+++++>-]+<<<<<<+>[<<[>->>>>>.[[-]<<<<]<<
<+>>>]>[->->>>>[-]]]<[->+[>>>>>]>>[<]<<<<<<<<[[-]<]>[++.[-]>>>>>>>]<]]>>]<[>>>>>
>>]+[-<<<<<[-]<<],]
带有格式和一些注释:
,
[
<<+>> >>+<<
[
[<+> >+<-]
++++++[>-------<-]
>-
[
not plus
-
[
not comma
-
[
not minus
-
[
not period
--------------
[
not less than
--
[
not greater than
<+++++[>------<-]>+
[
not open bracket
--
[
not close bracket
<<[-]>>-
]
]
<
]
>
[
greater than
>>-<<
<<<[-]<[<]<<<[<]
>>>>>>>>[<]
<-[+>]
+[->+]
>>>>+>[<-]
<[>+<-<]
>
]
<
]
>
[
less than
<<<[-]-[<]
>>>> >>>>>>>[<]
<<<<<<[<]
<-[+>]
+[-<+]
<<<+<[>-<<<]
>[-<+<]
]
]
<
]
>
[
minus
+>[-<]
<[<<]
<[-]>>
]
]
<
]
+>
[
plus
-[<-]
<[>+>+<<-<]
<[-]>+>
]
<<
[
comma or period or bracket
>-
]
>[,>]
<
]
comma or period or bracket or eof
<+<
[
start and end same cell
>
]
>
[
>>>
[
<<<<[-<]<<<
]
>>>+>>>>
[
start right of end
<<<<->>>>
[>>>[-<]>>>>]
]
]
>
[
<<<
[
<+[-->>]
]
>[-[.[-]]]
>[<]
>
[
<<++++++[>+++++++<-]>+>>
[<<.>>-]
<<++>-[<.>-]
+++[<+++++>-]
+<<<<< <+>
[
<<
[
go left
>->>>>>.
[[-]<<<<]
<<<+>>>
]
>
[
toggle left right
->->>>>[-]
]
]
<
[
toggle right left
->+[>>>>>]>>[<]
<<<<<<<<
[
[-]<
]
>
[
go right
++.[-]
>>>>>>>
]
<
]
]
>>
]
<[>>>>>>>]
+[-<<<<<[-]<<]
,
]
这使用与Keith Randall解决方案相同的方法,+-<>
通过仿真将所有连续序列最小化。例如,+++>-<+>---<
变为++++>----<
和>+<+<<+>+<->>>>
变为+<+>>+>
。
在线尝试。
(如果模拟单元的绝对值接近256,则将出现溢出问题。)
整体结构是
while not EOF:
while not EOF and next char not in ",.[]":
process char
print minified sequence (followed by the char in ",.[]" if applicable)
磁带分为7个单元的节点。在内部循环的开始,内存布局是
0 s 0 c 0 a b
其中s
是起始单元格的布尔值标志,c
是当前字符,a
是模拟单元格值的负数部分(加1),b
是模拟单元格值的正数部分。
打印缩小的序列时,内存布局为
d n e 0 0 a b
其中d
是用于方向的布尔标志,a
并且b
如之前(而成为一个印刷时/零),n
并且e
是唯一的非零对端节点; n
与看到该节点的次数有关,并且e
是停止内部循环的char的值(加1)。
最初,我考虑跟踪每个节点的更多信息:最左边和最右边的节点作为布尔标志,以及节点相对于开始节点和结束节点的位置。但是我们可以通过在需要时查看相邻单元格并进行左右扫描以找到起始节点来避免这种情况。
当打印缩小的序列并决定如何移动模拟指针时,我们可以采用一种通用方法:首先从末端节点移开(如果起始节点和末端节点相同,则朝任意方向移动),在最左端和最右端转向节点,然后根据看到结束节点的次数停止:如果开始节点和结束节点相同,则为3次,否则为2。
++>>++<<--
应该输出>>++<<
,这没有涵盖。请添加更多测试用例。