Черви гольфу Патерсона


11

Черви Патерсона - це своєрідний стільниковий автомат, який існує на нескінченній трикутній сітці і на кожному кроці вони повертаються в якомусь напрямку і рухаються однією одиницею. Їх визначальні властивості полягають у тому, що вони ніколи не можуть двічі переходити одне і те ж місце, і коли вони стикаються з одним і тим же оточенням, вони приймають те саме рішення. Черв'як завжди "бачить" з власної точки зору, його хвіст розташований в 3, а голова розташована в центрі цього шестикутника:

Зображення з wikipedia

Наприклад, розгляньте хробака з правилами:

  1. Якщо 0, 1, 2, 4 і 5 порожні, рухайтесь у напрямку 2
  2. Якщо 0, 1, 4 і 5 порожні, а 2 заповнено, рухайтесь у напрямку 0
  3. Якщо 0, 1 і 5 порожні, а 2 і 4 заповнені, рухайтесь у напрямку 0

Це призводить до наступного шляху (з Вікіпедії):

Черв'ячний шлях

Якщо черв’як опинився в ситуації, коли все оточення заповнене, він припиняється.

Вхідні дані

Список номерів. Четверте число вказує, яке рішення повинен прийняти черв'як у новій новій ситуації, з якою він стикається, коли йому належить прийняти рішення. Зауважте, що якщо все, крім одного його оточення, заповнене, воно повинне рухатись лише в порожньому напрямку. Це не вважається "рішенням" і не споживає кількості. Щоб генерувати приклад черв'яка, показаний вище, вхід буде [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)

Наступна поспішно зібрана (можливо, баггі) програма відобразить хробаків:



Чи можемо ми взяти вхід у зворотному порядку?
Арнольд

1
@Arnauld впевнений, що здається нормальним
soktinpk

Відповіді:


4

JavaScript (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

К (нг / к) , 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 - поточний напрямок, що використовується як індексний модуль 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і зберегти виразний, тобто Append , pщоб mтільки тоді , коли pне відбувається вm

$[... ;... ;... ]якщо-то-інше

c:X m?pзнайти індекс pв mі використовувати його як індекс в X. результати індексації поза межами межі в 0N("null")

$[(~p)|^c:X m?p;x;... ]якщо p0 (немає шляху виходу) або cє 0N, тоді повернення, xяке змусить конвергенцію і зупинить цикл

x,,h+D 6!d+:cінше прикладіть нову голову до xі повторіть

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.