帕特森高尔夫蠕虫


11

帕特森蠕虫是一种细胞自动机,存在于无限的三角形网格中,每走一步,它们就会朝某个方向旋转并移动一个单位。它们的定义特性是,它们永远不会两次经过相同的地点,并且每当遇到相同的环境时,他们都会做出相同的决定。蠕虫总是从自己的角度“看到”,其尾巴位于3处,其头部位于此六角形的中心:

图片来自维基百科

例如,考虑使用以下规则的蠕虫:

  1. 如果0、1、2、4和5都为空,则沿方向2移动
  2. 如果0、1、4和5为空白,并且填充了2,则沿方向0移动
  3. 如果0、1和5为空白,而2和4已填充,则沿方向0移动

这将导致以下路径(来自Wikipedia):

蠕虫路径

如果蠕虫发现自己处于周围所有环境都被淹没的状态,它将终止。

输入值

数字列表。第n个数字表示蠕虫应在必须做出决定的第n个新情况下做出什么决定。请注意,如果除了一个周围的环境外,其他所有空间都被填充,则它必须沿唯一的空白方向移动。这不算作“决定”,也不消耗数字。要生成上面显示的示例蠕虫,输入为[2, 0, 0]。确保输入产生蠕虫,该蠕虫会终止并且不会回溯其路径,并且输入永远不会太短。

输出量

从处开始输出坐标列表,以指示蠕虫头所在的位置(1, 0)。我们将考虑向上和向右移动仅是y值的减小,而向上和向左移动则是x值的减小和y值的减小。例如,示例输入的路径输出为

(1, 0), (1, 1), (0, 0), (-1, -1), (0, -1), (0, 0), (0, 1), (-1, 0), (0, 0)

测试用例

您也可以使用javascript代码段运行测试。

[2,0,0]: (1,0),(1,1),(0,0),(-1,-1),(0,-1),(0,0),(0,1),(-1,0),(0,0)
[1,0,4,0,1,5]: (1,0),(2,1),(2,2),(1,2),(0,1),(0,0),(0,-1),(1,-1),(2,0),(2,1),(3,1),(4,2),(4,3),(3,3),(2,2),(1,1),(1,0),(2,0),(3,1),(3,0),(4,0),(5,1),(5,2),(4,2),(3,2),(2,1),(1,1),(0,0),(-1,0),(-2,-1),(-2,-2),(-1,-2),(0,-1),(1,0),(1,-1),(2,-1),(3,0),(4,1),(4,2),(5,3),(5,4),(4,4),(3,3),(3,4),(2,4),(1,3),(1,2),(1,1),(0,1),(-1,0),(-1,1),(-2,1),(-3,0),(-3,-1),(-2,-1),(-1,-1),(0,0)
[1,0,5,1]: (1,0),(2,1),(2,2),(1,2),(0,1),(0,0),(0,-1),(1,-1),(2,0),(2,1),(3,2),(3,3),(2,3),(1,2),(0,2),(-1,1),(-1,0),(0,0),(1,1),(1,2),(1,3),(0,3),(-1,2),(-1,1),(-2,0),(-2,-1),(-1,-1),(0,0)
[2,0,1,0]: (1,0),(1,1),(0,0),(-1,-1),(0,-1),(0,0),(-1,0),(-1,-1),(-1,-2),(0,-1),(1,0),(2,1),(1,1),(0,1),(0,0)

以下匆忙组装的(可能是越野车)程序将显示蠕虫:


2
建议的测试用例:p(这是[1,0,4,2,0,1,5]。)
Arnauld

我们可以按相反的顺序进行输入吗?
Arnauld

1
@Arnauld确定看起来还不错
soktinpk

Answers:


4

的JavaScript(ES6), 261个250  249字节

[Xÿ]

a=>(G=[[[x=1]]],v=[0,1,1,0,-1,-1],F=y=>[[x,y],...v.every((_,i)=>k^=g(o+i)[q%3]<<i,k=63,g=o=>(r=G[Y=y-o%2*v[q=(o+3)%6]]=G[Y]||[])[X=x-o%2*v[-~q%6]]=r[X]||[])?F(y+v[g(o+=F[k]|=1/F[k]?0:k&~-k?a.pop():31-Math.clz32(k))[q%3]=1,o%6],x+=v[-~o%6]):[]])(o=0)

在线尝试!

这实际上是演示代码段的端口。


4

K(ngn / k),115个字节

D,:-D:2\6 3;f:{d::0;m::2/=6;X::(!6),x;{m::?m,p:2/^(+':x)?(2*h:*|x)+/:D 6!d+!6;$[(~p)|^c:X m?p;x;x,,h+D 6!d+:c]}/,1 0}

(不计算功能命名部分f:

在线尝试!

D,:-D:2\6 3 产生六个基本方向 (1 0;1 1;0 1;-1 0;-1 -1;0 -1)

d::0 是当前方向,在其中用作索引mod 6 D

m::2/=6产生最初的蠕虫记忆32 16 8 4 2 1。每个数字的位对周围环境进行编码(0 =已访问段; 1 =未访问)。最初m仅包含明确的环境-可以使用单个出口的环境。

X::(!6),x是蠕虫的规则。我们假设0 1 2 3 4 5匹配的原始明确环境m

{... }/,1 0应用直到收敛{ }以1个元素的列表开头的函数1 0。该列表将包含蠕虫访问的成对坐标。

D 6!d+!6六个基本方向,从d顺时针开始

h:*|x 最后一个参数,即蠕虫头部的位置

(2*h:*|x)+/:D 6!d+!6将头部的坐标乘以2,然后加上基本方向。这是我们表示点之间的线段的方式。

+':x 添加成对的相邻访问点-这使我们可以看到它们之间的线段

^(…… )?找出尚未访问过的头部周围部分

p:2/ 二进制编码并分配给 p

m::?m,p追加到m并保持明显的,即追加pm只有在p不发生m

$[... ... ;... ... ;... ... ]IF-THEN-ELSE

c:X m?p找到pin 的索引m并将其用作in的索引X。越界索引导致0N(“ null”)

$[(~p)|^c:X m?p;x;... ]如果p为0(无退出路径)或c0N,则返回return x,将强制收敛并停止循环

x,,h+D 6!d+:c否则将新的头附加x并重复

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.