골프 패터슨 웜


11

패터슨의 벌레 는 무한 삼각 격자에 존재하는 일종의 세포질 오토 마톤이며, 모든 단계에서 어떤 방향으로 돌리고 한 단위를 움직입니다. 그들의 정의 속성은 그들이 같은 지점을 두 번 넘을 수 없으며, 동일한 환경을 만날 때마다 같은 결정을 내린다는 것입니다. 웜은 항상 꼬리가 3에 있고 머리가이 육각형의 중앙에있는 자체 관점에서 "인식"합니다.

Wikipedia의 이미지

예를 들어 다음 규칙을 가진 웜을 고려하십시오.

  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)

테스트 사례

자바 스크립트 스 니펫을 사용하여 테스트를 실행할 수도 있습니다.

[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

답변:


4

자바 스크립트 (ES6),  261 250  249 바이트

[x,y]

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 6 개의 기본 방향을 생성합니다 (1 0;1 1;0 1;-1 0;-1 -1;0 -1)

d::0 인덱스 방향 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 요소 목록으로 시작 }/,1 0하는 함수가 수렴 될 때까지 적용 { }하십시오 1 0. 이 목록에는 웜이 방문한 좌표 쌍이 포함됩니다.

D 6!d+!6d시계 방향으로 시작 하고 돌아가는 6 가지 기본 방향

h:*|x 논쟁의 마지막, 즉 벌레의 머리의 위치

(2*h:*|x)+/:D 6!d+!6머리 좌표에 2를 곱하고 기본 방향을 추가하십시오. 이것이 포인트 사이의 세그먼트를 나타내는 방법입니다.

+':x 인접한 방문 지점 쌍을 추가하십시오-이것은 우리 사이에 세그먼트의 표현을 제공합니다

^(... )?... 헤드의 주변 세그먼트 중 아직 방문하지 않은 부분을 찾으십시오.

p:2/ 이진 인코딩 및 할당 p

m::?m,p추가하는 m과 구별되는, 즉 APPEND 유지 p하는 m경우에만이 p발생하지 않습니다m

$[... ;... ;... ]if-then-else

c:X m?p의 인덱스 찾을 수 p있는을 m하고있는 인덱스로 사용합니다 X. 범위를 벗어난 인덱싱 결과 0N( "null")

$[(~p)|^c:X m?p;x;... ]경우 p0 (출구 경로) 또는 c0N다음 Return x수렴 강제 루프를 중지 할

x,,h+D 6!d+:c그렇지 않으면 새 머리를 추가 x하고 반복하십시오.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.