Чисто , 284 279 272 262 байт
import StdEnv
l=[0,-1,-1,0,1,1]
c(u,v)(p,q)=(u-p)^2+(v-q)^2<2||(u-p)*(q-v)==1
$[h:t]m=hd[[e: $t[(h,e):m]]\\e<-[1..]|and[e<>j\\(u,v)<-m|c h u,(p,q)<-m|q==v,(i,j)<-m|c p i]]
$(scan(\(a,b)(u,v)=(a-u,b-v))(0,0)[(i,j)\\n<-[1..],i<-[1,1:l]&j<-l,_<-[max(~j<<i)1..n]])[]
Спробуйте в Інтернеті!
Створює послідовність назавжди.
Шестикутник
Більшість коду належить до відображення шестикутників однозначно для (x,y)
координат, щоб існувала єдина, проста функція для визначення суміжності, яка виконується для всіх відображень точок.
Зображені точки виглядають так:
---
--- < 2,-2> --- x-axis ___.X'
--- < 1,-2> === < 2,-1> --- /__.X'
< 0,-2> === < 1,-1> === < 2, 0>'
=== < 0,-1> === < 1, 0> ===
<-1,-1> === < 0, 0> === < 1, 1>
=== <-1, 0> === < 0, 1> ===
<-2, 0> === <-1, 1> === < 0, 2>.__
--- <-2, 1> === <-1, 2> --- \ 'Y.___
--- <-2, 2> --- y-axis 'Y.
---
Звідти визначення суміжності тривіальне і відбувається, коли один із:
x1 == x2
і abs(y1-y2) == 1
y1 == y2
і abs(x1-x2) == 1
y1 == y2 - 1
і x2 == x1 - 1
y1 == y2 + 1
і x2 == x1 + 1
x1 == x2
і y1 == y2
Покоління точок
Зауважте, що при переході шестикутника по спіралі відмінності повторюються для кожного шару n
:
n
кроки (1,0)
n-1
кроки (1,-1)
n
кроки (0,-1)
n
кроки (-1,0)
n
кроки (-1,1)
n
кроки (0,1)
Це створює точки в правильному порядку, беручи суми префіксів цієї послідовності:
scan(\(a,b)(u,v)=(a-u,b-v))(0,0)[(i,j)\\n<-[1..],i<-[1,1:l]&j<-l,_<-[max(~j<<i)1..n]]
Об’єднавши його
Код, який фактично знаходить послідовність із запитання, просто:
$[h:t]m=hd[[e: $t[(h,e):m]]\\e<-[1..]|and[e<>j\\(u,v)<-m|c h u,(p,q)<-m|q==v,(i,j)<-m|c p i]]
Що, в свою чергу, в основному фільтрує and[r<>j\\(u,v)<-m|c h u,(p,q)<-m|q==v,(i,j)<-m|c p i]
Цей фільтр приймає бали m
(список уже нанесених точок) за:
- Ігнорування натуральних чисел, рівних будь-яким
j
- Для кожного,
(i,j)
де i
є сусіднімp
- Для кожного,
(p,q)
де значення q
дорівнюєv
- Для кожного місця,
(u,v)
де u
примикає до поточної точки