나선형 시퀀스


29

배경

OEIS 시퀀스 A272573 은 다음과 같이 육각형 그리드의 나선형을 나타냅니다.

육각형 타일링에서 숫자의 나선을 시작하십시오. 초기 육각형은 a (1) = 1입니다. a (n)은 이웃과 같거나 이전에 인접하지 않은 가장 작은 양의 정수입니다.

순서가 시작됩니다

1, 2, 3, 4, 5, 6, 7, 4, 6, 8, 5, 9, 8, 10, 2, 11, ...

나선형 패턴의 그림은 다음과 같습니다. 여기에 이미지 설명을 입력하십시오

  • a(11) != 1다음 때문에 3그리고 1이 곳에서 인접 것입니다.
  • a(11) != 2다음 때문에 3그리고 2이 곳에서 인접 것입니다.
  • a(11) != 33그 자체가 인접 할 것이기 때문 입니다.
  • a(11) != 4다음 때문에 3그리고 4이 곳에서 인접 것입니다.
  • 따라서 a(11) = 5.

도전

문제는 A272573 을 계산하는 프로그램을 작성하는 입니다. 이것은 이므로 가장 짧은 코드가 승리합니다.


여기에서 차단 된 이미지를 볼 수 없으므로 뭔가
빠졌을

실수로 실수를 잡아 주셔서 감사합니다.
피터 카게이

7
이 OEIS 시퀀스는 분명히 직접 제출했습니다. 좋은. :)
Arnauld

n의 한계는 무엇입니까? 시간 제한이 있습니까?
Setop December

5
Hexagony 답변을 기다리는 중 ...
Jonathan Allan

답변:


23

자바 스크립트 (ES6),  267 ~ 206  199 바이트

시퀀스 의 번째 항을 포함하는 배열을 반환합니다 .

n=>(F=v=>++i<n?F([...v,(A=N[i]=[1,!j++||d+1,j%L?d:(j%=L*6)?++d:L++&&d++].map(k=>N[k=i-k].push(i)&&k),g=k=>v[E='every']((V,x)=>V-k|N[x][E](y=>A[E](z=>v[y]-v[z])))?k:g(-~k))()]):v)([L=1],N=[[i=j=d=0]])

온라인으로 사용해보십시오!

방법?

정의

관례 적으로, 우리는 호출 코너 셀 나선 및 이전 층과 공통 단지 하나의 에지가있는 셀 사이드 셀 은 이전 층과 공통 개의 에지를 갖는 세포. Ourous에 의해 제안 된 바와 같이 , 우리는 그것들을 각각 순서 1 셀과 순서 2 셀로 생각할 수 있습니다.

코너 셀은 아래 노란색으로 표시됩니다. 다른 모든 셀은 사이드 셀입니다 (특별한 경우 인 중앙 셀 제외).

세포 유형

셀 이웃에 대하여

그리드에서 셀의 좌표를 추적 할 필요는 없습니다. 우리가 알아야 할 유일한 것은 주어진 시간에 나선형으로 각 셀에 대한 인접 셀 목록입니다.

다음 다이어그램에서 이전 레이어의 이웃은 밝은 음영으로 표시되고 현재 레이어의 추가 이웃은 어두운 음영으로 표시됩니다.

다음과 같은 경우 셀 에 이전 셀 사이에 2 개의 이웃 이 있습니다.

  • 새 레이어의 첫 번째 사이드 셀입니다 (예 : 8 )
  • 또는 모서리 셀이지만 레이어의 마지막 레이어는 아닙니다 (예 : 9 )

2 명의 이웃

다음과 같은 경우 셀 에 이전 셀 사이에 3 개의 이웃 이 있습니다.

  • 사이드 셀이지만 레이어의 첫 번째 레이어는 아닙니다. 10 )
  • 또는 현재 레이어의 마지막 모서리 셀입니다 (예 : 19 )

3 명의 이웃

셀 이웃의 구현

현재 셀의 색인 ( 1)에 저장됩니다 나는. 셀의 이웃 목록 에 저장된다 에이[].

불명확 한 골프 이유로, 먼저 이웃의 반대 오프셋을 계산합니다. 예를 들어1 방법 1이전 셀 을 의미 합니다 .

[                    //
  1,                 // the previous cell is always a neighbor of the current cell
  !j++ || d + 1,     // if this is not the first cell of the layer, the cell at -(d + 1)
                     // is a neighbor (otherwise, we insert 1 twice; doing it that way
                     // saves bytes and having duplicate neighbors is not a problem)
  j % L ?            // if this is a side-cell:
    d                //   the cell at -d is a neighbor
  :                  // else (corner-cell):
    (j %= L * 6) ?   //   if this is not the last cell:
      ++d            //     insert the dummy duplicate neighbor at -(d + 1); increment d
    :                //   else (last cell):
      L++ && d++     //     the cell at -d is a neighbor; increment L; increment d
]                    //

위 코드에서

  • 에서 시작하는 현재 레이어의 인덱스입니다. 1 (중앙 셀을 세지 않음).
  • j 현재 레이어 내에서 현재 셀의 인덱스입니다. 16×.
  • 는 현재 셀과 이전 레이어의 거리입니다. 코너 셀을 통과 할 때마다 증가합니다.

그런 다음 map()오프셋을 변환 하는 루프 를 처리 합니다.케이 색인으로 (나는케이) 이웃 셀을 강화하기 위해 현재 셀을 모든 이웃 셀의 새 이웃으로 푸시합니다.

.map(k =>
  N[k = i - k].push(i) && k
)

순서의 다음 항 찾기

모든 셀에 대한 최신 이웃 목록이 있으므로 이제 다음 항을 계산할 수 있습니다 케이 다른 재귀 도우미 함수를 사용하여 시퀀스의

셀의 가치 에 저장된다 V[].

( g =                 // g = recursive function taking
  k =>                // the candidate value k
    v.every((V, x) => // for each previous cell of value V at position x, make sure that:
      V - k           //   V is not equal to k
      |               //   OR
      N[x].every(y => //   for each neighbor y of x:
        A.every(z =>  //     for each neighbor z of the current cell:
          v[y] - v[z] //       the value of y is not equal to the value of z
        )             //     end
      )               //   end
    )                 // end
    ?                 // if the above conditions are fulfilled:
      k               //   stop recursion and return k
    :                 // else:
      g(-~k)          //   try again with k + 1
)()                   // initial call to g with k undefined (this will cause V - k to be
                      // evaluated as NaN and force the 1st iteration to fail)

좋은 설명입니다. 한 가지 가능한 개선 사항 : 수평 스크롤없이 코드 블록의 설명을 완전히 볼 수 있습니다 (골프 코드에는 중요하지 않음). Firefox에서 볼 때 첫 번째 설명 코드 블록에는 5 개의 숨겨진 열이 있고 두 번째에는 6 개의 숨겨진 열이 있습니다.
trichoplax

@trichoplax 의견과 제안에 감사드립니다. 사용중인 Firefox 버전과 플랫폼을 지정할 수 있습니까? 가로 스크롤이 필요하지 않도록 항상 설명 블록을 형식화하려고합니다. 현재 Firefox 65 / Win10을 사용하고 있으며 숨겨진 열이 없습니다.
Arnauld

집에 도착하면 Firefox 버전을 확인하지만 Fedora를 사용하고 있기 때문일 수 있습니다. 다른 OS를 확인하고 알려드립니다
trichoplax

1
OS에 따라 다릅니다. 증거를 수집 할 기회가 있었을 때 MSE에서이 문제를 제기 할 것입니다 (아직없는 경우)
trichoplax

1
나는 이것을 MSE에서 올렸다 . 가로 스크롤 막대를 표시하는 다른 OS / 브라우저 조합이 표시되면 자유롭게 편집하십시오.
trichoplax

7

청소 , 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 == x2abs(y1-y2) == 1
  • y1 == y2abs(x1-x2) == 1
  • y1 == y2 - 1x2 == x1 - 1
  • y1 == y2 + 1x2 == x1 + 1
  • x1 == x2y1 == y2

포인트 생성

나선형으로 육각형을 가로 지르는 경우 각 레이어마다 차이가 반복됩니다 n.

  1. n 의 단계 (1,0)
  2. n-1 의 단계 (1,-1)
  3. n 의 단계 (0,-1)
  4. n 의 단계 (-1,0)
  5. n 의 단계 (-1,1)
  6. 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
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.