Worms de Paterson de golfe


11

Os vermes de Paterson são um tipo de autômato celular que existe em uma grade triangular infinita e, a cada passo, eles se voltam em alguma direção e movem uma unidade. Suas propriedades definidoras são que eles nunca podem percorrer o mesmo local duas vezes e, sempre que encontram o mesmo ambiente, tomam a mesma decisão. Um verme sempre "vê" de sua própria perspectiva, com a cauda localizada em 3 e a cabeça localizada no centro deste hexágono:

Imagem da wikipedia

Por exemplo, considere o worm com as regras:

  1. Se 0, 1, 2, 4 e 5 estiverem em branco, vá na direção 2
  2. Se 0, 1, 4 e 5 estiverem em branco e 2 estiver preenchido, mova na direção 0
  3. Se 0, 1 e 5 estiverem em branco e 2 e 4 estiverem preenchidos, mova na direção 0

Isso resulta no seguinte caminho (da Wikipedia):

Caminho de verme

Se o verme se encontra em uma situação em que todos os arredores estão cheios, ele termina.

Entrada

Uma lista de números. O enésimo número indica que decisão o worm deve tomar na enésima nova situação que encontra onde deve tomar uma decisão. Observe que, se todos, exceto um de seus arredores, estiverem preenchidos, ele deverá se mover na única direção que estiver vazia. Isso não conta como uma "decisão" e não consome um número. Para gerar o exemplo de worm mostrado acima, a entrada seria [2, 0, 0]. A entrada é garantida para produzir um worm que termina e não refaz seu caminho, e a entrada nunca será muito curta.

Resultado

Crie uma lista de coordenadas indicando onde está a cabeça do worm, começando em (1, 0). Consideraremos mover para cima e para a direita como uma diminuição apenas no valor y, mas mover para cima e para a esquerda será uma diminuição no valor x e uma diminuição no valor y. Por exemplo, a saída do caminho para a entrada de exemplo é

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

Casos de teste

Você pode usar o snippet javascript para executar testes também.

[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)

O seguinte programa montado às pressas (possivelmente com bugs) exibirá os worms:


2
Caso de teste sugerida : p (Isto é [1,0,4,2,0,1,5].)
Arnauld

Podemos pegar a entrada na ordem inversa?
Arnauld

1
@Arnauld certeza de que parece ok
soktinpk

Respostas:


4

JavaScript (ES6),  261 250  249 bytes

[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)

Experimente online!

Essa é essencialmente uma porta do snippet de demonstração.


4

K (ngn / k) , 115 bytes

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}

(sem contar a parte de nomeação da função f:)

Experimente online!

D,:-D:2\6 3 gera as seis direções cardeais (1 0;1 1;0 1;-1 0;-1 -1;0 -1)

d::0 é a direção atual, usada como um índice mod 6 em D

m::2/=6gera a memória inicial do worm 32 16 8 4 2 1. os bits de cada número codificam o ambiente (0 = segmento visitado; 1 = não visitado). inicialmente mcontém apenas ambientes não ambíguos - aqueles em que uma única saída está disponível.

X::(!6),xsão as regras do worm. prependemos 0 1 2 3 4 5para combinar com o ambiente inequívoco inicial em m.

{... }/,1 0aplique até a convergência a função { }começando com uma lista de 1 elemento contendo 1 0. a lista conterá pares de coordenadas visitadas pelo worm.

D 6!d+!6as seis direções principais, começando de girando no sentido horário

h:*|x último argumento, ou seja, a posição da cabeça do verme

(2*h:*|x)+/:D 6!d+!6multiplique as coordenadas da cabeça por 2 e adicione as direções cardinais. esta é a nossa maneira de representar os segmentos entre pontos.

+':x adicionar pares de pontos visitados adjacentes - isso nos dá as representações dos segmentos entre eles

^(... )?... descubra quais segmentos adjacentes da cabeça ainda não foram visitados

p:2/ codificação binária e atribuir a p

m::?m,pacréscimo para me manter a distinta, ou seja, de acréscimo pde msomente se pnão ocorrer emm

$[... ;... ;... ]se-então-outro

c:X m?pencontre o índice de pin me use-o como um índice em X. A indexação fora dos limites resulta em 0N("nulo")

$[(~p)|^c:X m?p;x;... ]se pé 0 (sem caminho de saída) ou cé 0N, então retorne o xque forçará a convergência e interromperá o loop

x,,h+D 6!d+:ccaso contrário, anexe a nova cabeça xe repita

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.