我以为我会利用这个机会来展示Retina的新功能:多级循环。这将大大缩短许多任务(尤其是有条件的替换)。
ii
-
+`(.)\1|0
(.)-|(\d)(\d)
-$1$3$2
12
i3
23
i1
31
i2
)`(\d)i
i$1
^\D*$
$&0
视网膜是我自己的基于正则表达式的编程语言。源代码可以分为多个阶段:每个阶段由两行组成,其中第一行包含正则表达式(可能包含某些配置),第二行是替换字符串。然后将这些阶段按顺序应用于STDIN,并将最终结果打印到STDOUT。
您可以使用-s
命令行开关将以上内容直接用作源文件。但是,我没有算在内,因为您还可以将每行放在一个单独的文件中(然后,换行符会丢失15个字节,而其他文件会加+15)。
说明
此解决方案的新事物是)
倒数第二阶段。这将关闭多级循环。没有匹配项(
,这意味着循环隐式开始于第一阶段。因此,重复前7个阶段,直到全部通过所有这7个阶段都停止更改结果为止。这7个阶段仅执行各种转换即可逐渐减少字符串中矩阵的数量并合并阶段。一旦达到最终结果,这七个模式便不再匹配,循环结束。然后,如果结果中还没有数字,我们会附加一个0(因为上述阶段只是删除了所有身份,包括结果)。
以下是各个阶段的工作:
ii
-
将所有对i
进-
,以减少相位字符。
+`(.)\1|0
<empty>
现在,如果剩下两个连续的相同字符,则为一个--
或两个相同的矩阵。在任何一种情况下,将它们相乘即可得出身份。但是我们不需要身份,因此我们只需删除所有身份以及显式身份(0
s)。重复此阶段,+
直到结果停止更改为止。这样可以确保123321
完全解决类似问题,从而使下一步可以假定所有数字对都是不同的。
(.)-|(\d)(\d)
-$1$3$2
实际上,这是一个单独的两个转换(用于高尔夫度)。请注意,如果第一个选项匹配,$2
并且$3
为空,并且第二个匹配项$1
为空。因此,可以将其分解为以下两个步骤:
(\d)(\d)
-$2$1
这只是交换所有数字对并添加减号。因为我们删除了所有0
S和所有相同的对,这将只匹配12
,23
,31
,21
,32
,13
。这一步似乎很奇怪,但是它允许我以后只检查其中一半,因为我无法处理的情况将在下一次迭代中交换。
上述阶段的另一部分是:
(.)-
-$1
这会逐渐将-
符号一直移到左侧(每次迭代一个位置)。我这样做是为了最终使它们彼此相邻并在较早的步骤中得到解决。
12
i3
23
i1
31
i2
这三个阶段现在只需解决三对产品。就像我在上面说的那样,这只会捕获一半的相关案例,但是另一半将在上一步交换所有对之后的下一次迭代中得到解决。
)`(\d)i
i$1
这是循环的最后阶段。-
除了以外,它类似于向左移动的那个i
。主要区别在于,这一位i
仅与数字交换。如果我使用了(.)i
then,那么在我得到a -i
或i-
2的情况下,它们将被无限期交换,并且程序不会终止。因此,这仅将它们交换到-
标志的右侧。这是不够的-只要所有-
,并i
在某些时候一起出现,它们可以被正确解析。
^\D*$
$&0
最后一步(循环之外)。请记住,我们总是删除所有身份,因此,如果结果实际上是身份(乘以一个阶段),则输出中将不再有所需的数字,因此将其添加回去。
例如,以下是所有的中间形式0223202330203313021301011023230323
(不执行任何更改的跳过阶段):
0223202330203313021301011023230323
321321312 # Remove identities
-23-31-12-132 # Swap all pairs
-23-31-i3-132 # Resolve 12
-i1-31-i3-132 # Resolve 23
-i1-i2-i3-132 # Resolve 31
-i-1i-2i-3-312 # Move - to the left and swap pairs
-i-1i-2i-3-3i3 # Resolve 12
-i-i1-i2-3-i33 # Move i to the left
-i-i1-i2-3-i # Remove identities
--ii-1i-2-3i # Move - to the left
--ii-i1-2-i3 # Move i to the left
----i1-2-i3 # Resolve ii
i1-2-i3 # Remove identities
i-1-2i3 # Move - to the left
i-1-i23 # Move i to the left
-i-1i-32 # Move - to the left and swap pairs
-i-i1-32 # Move i to the left
--ii-1-23 # Move - to the left and swap pairs
--ii-1-i1 # Resolve 23
----1-i1 # Resolve ii
1-i1 # Remove identities
-1i1 # Move - to the left
-i11 # Move i to the left
-i # Remove identities. Now the loop can't change this any longer.
-i0 # Fix the result by adding in the 0.