クリーン、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