계단으로 계단 타일링

Sep 08 2020

배경

계단 폴리오 미노는 형상이 계단 부 유사한 사각형 이루어진 폴리오 미노이다. 좀 더 공식적으로, 크기 \ 의 계단 폴리오 미노$n\$ 다음과 같이 정의됩니다.

  • 크기 1의 계단 폴리오 미노는 단일 단위 사각형입니다.
  • \ 크기의 계단 폴리오 미노$n\$크기와 동일합니다 \$n-1\$가로 막대 길이 \$n\$ 하단에 부착되어 왼쪽 정렬됩니다.

간결함을 위해 그냥 계단 이라고 부르 자 .

예를 들어, 다음은 크기 1에서 4까지의 계단입니다.

#

#
##

#
##
###

#
##
###
####

도전

양의 정수 \$n\$, 크기의 계단 방법의 수를 계산 \$n\$ 하나 이상의 계단으로 바둑판 식으로 배열 할 수 있습니다.

같은 크기의 여러 계단을 타일링에 사용할 수 있으며 계단을 회전 할 수 있습니다. 따라서 다음은 \에 대한 유효한 타일링입니다.$n=4\$:

A
BC
DEF
GHIJ

A
AA
AAA
AAAA

A
AA
BBC
BDCC

표준 코드 골프 규칙이 적용됩니다. 바이트 단위의 가장 짧은 코드가 이깁니다.

테스트 케이스

이 Python 3 참조 솔루션을 사용하여 생성되었습니다 .

1 -> 1
2 -> 2
3 -> 8
4 -> 57
5 -> 806
6 -> 20840
7 -> 1038266

답변

12 Arnauld Sep 09 2020 at 06:54

JavaScript (ES10),  250 ...  228227 바이트

n=>(e=g=(a,[x]=a)=>+e?e=0:(x&=-x)?a.map((_,s)=>[b=1<<s,...s?[1,b+=~-b,b]:[]].map((m,d)=>d|x>>s&&g(a.flatMap(S=(v,y)=>(S|=y>s?v:(e|=(v^=M=x*m>>!d*s)&M,m^=1<<[s+~y,y+1,s-y,y][d],v))?v:[])))):n++)([...Array(n)].map(_=>2**n---1))|n

온라인으로 시도하십시오!

어떻게?

크기- \$n\$계단을 배열하여 설명 \$a[\:]\$의 \$n\$ 가장 긴 행에서 가장 짧은 행으로가는 비트 마스크.

대한 \$n=4\$, 이것은 다음을 제공합니다.

# # # #  0b1111 = 15
. # # #  0b0111 = 7
. . # #  0b0011 = 3
. . . #  0b0001 = 1  --> a = [ 15, 7, 3, 1 ]

반복 할 때마다 \의 모든 선행 빈 행을 제거합니다.$a[\:]\$최하위 0이 아닌 비트 \$x\$비어 있지 않은 첫 번째 행. 그 주 \$x\$이 비트의 인덱스로 설정되지 않고 \ 의 해당 거듭 제곱으로 설정됩니다.$2\$.

각 \$s\in[0\:..\:n-1]\$우리는 크기의 또 다른 계단 주요 계단을 커버하려고 \$s+1\$0이 아닌 비트에 고정되고 행이 비트 마스크 \ 로 설명됩니다.$m\$. 만약 \$s=0\$, 우리는 오리엔테이션 \$d=0\$. 그렇지 않으면 \$d=0\$에 \$d=3\$.

아래 표는 \의 각 값에 대해 설명합니다.$d\$:

  • 초기 값 \$m\$
  • \ 에서 반전되어야하는 비트의 인덱스$m\$ 다음 행을 생성하려면
  • \에 적용된 시프트$m\$

계단이 고정되는 0이 아닌 비트는 A. 모든 경우에 \$m\$먼저 \를 곱합니다.$x\$이동하기 전에. 모든 예는 \ 와 함께 제공됩니다.$x=16\$및 \$s=2\$.

             x           d = 0
       . . . . . . . .
y = 0        A           init.  : 2 ** s
y = 1        # #         bit    : s + ~y  (i.e. s - y - 1)
y = 2        # # #       shift  : >> s
       
             x           d = 1
       . . . . . . . .
y = 0        A           init.  : 1
y = 1      # #           bit    : y + 1
y = 2    # # #           shift  : none
       
             x           d = 2
       . . . . . . . .
y = 0    # # A           init.  : 2 * (2 ** s) - 1
y = 1      # #           bit    : s - y
y = 2        #           shift  : none
       
             x           d = 3
       . . . . . . . .
y = 0    # # A           init.  : 2 * (2 ** s) - 1
y = 1    # #             bit    : y
y = 2    #               shift  : none

참고 : 0이 아닌 비트의 오른쪽에있는 비트가 정의에 따라 모두 지워지고 위에서 아래로 이동한다는 점을 감안할 때 덮는 계단의 앵커 포인트는 각 방향에 대해 명확하게 정의됩니다.

5 Neil Sep 09 2020 at 12:12

차콜 , 91 88 87 83 81 78 바이트

≔⊕Nθ⊞υEθ⁻X²θX²ιF⊖θFθFE²Eθ×÷⊖X²θX²⁺ινX²⁺κ∧λνF⟦λ⮌λ⟧FθFυF¬⊙ξ&π§μ⁻ρν⊞υEξ|ρ§μ⁻ςνILυ

온라인으로 시도하십시오! 링크는 자세한 코드 버전입니다. 여기에는 루프가 너무 많아서 v처음으로 변수에 도달했습니다 . 설명:

≔⊕Nθ

계단의 크기를 입력하고 증가시킵니다.

⊞υEθ⁻X²θX²ι

구멍이 원점에있는 방식으로 해당 크기의 계단을 만듭니다. 구멍은 우리가 원했던 원래 크기 인 한 크기 더 낮습니다. 이것은 초기 타일링 (크기 1 계단으로 원래 계단의 타일링을 나타냄)이됩니다. 계단은 비트 마스크의 배열로 표시됩니다.

F⊖θ

1보다 큰 모든 계단 크기를 고려하십시오 (크기 1 계단은 각 잠재적 타일링에 대해 남아있는 구멍을 채우는 데 사용된다고 가정하여 고려됩니다.)

Fθ

모든 수평 번역을 고려하십시오.

FE²Eθ×÷⊖X²θX²⁺ινX²⁺κ∧λν

수평으로 변환 된 계단과 수평 반사 (실제로 전단에 의해 얻어 짐)를 고려하십시오.

F⟦λ⮌λ⟧

또한 그 계단의 수직 반사를 고려하십시오. (수직 변환이 주기적이므로 작동합니다.)

Fθ

또한 그 계단의 모든 순환 수직 변환을 고려하십시오. 수직 평행 이동은 주기적이므로 조각을 너무 수평으로 이동하는 평행 이동은 항상 계단과 겹칩니다.

Fυ

지금까지 수집 된 모든 타일링을 반복합니다.

F¬⊙ξ&π§μ⁻ρν

계단이이 위치의 구멍에 맞으면 ...

⊞υEξ|ρ§μ⁻ςν

... 구멍에 배치 한 결과를 타일링 목록에 추가합니다. (Charcoal은이 결과를 목록에서 다시 찾을 수 있지만 물론 두 번 배치 할 수는 없습니다.)

ILυ

발견 된 타일링 수를 출력합니다.

불가능한 위치에 계단을 놓지 않는 예 :

   \
  \\
 \\\
\\\\/
   //

예를 들어, 크기 2 계단의 이중 반사는 수평 및 수직으로 3만큼 움직일 수 있으며, 이는 일반적으로 원래 계단 밖으로 떨어지고 구멍을 완전히 놓치게합니다. 그러나 수직 변환은 주기적이므로 실제 결과는 다음과 같습니다.

   X/
  \\
 \\\
\\\\/

따라서 이것은 잘못된 타일링으로 감지됩니다.