비밀“>”스태킹 과제 : 채점

Aug 18 2020

배경

Tetris Grand Master 3 에는 게임이 끝날 때 스택 모양을 기반으로하는 숨겨진 등급 시스템이 있습니다.이를 Secret ">"Stacking Challenge라고 합니다. 왼쪽 하단 셀에서 시작하여 전체 너비에 걸쳐있는 지그재그 패턴을 제외하고는 가장 낮은 행을 완전히 채우는 것으로 구성됩니다.

#
.#########
#.########
##.#######
###.######
####.#####
#####.####
######.###
#######.##
########.#
#########.
########.#
#######.##
######.###
#####.####
####.#####
###.######
##.#######
#.########
.#########

보드는 최종 라인에서이 정확한 패턴을 따르는 라인 수에 따라 등급이 매겨집니다. 패턴의 맨 위 구멍은 추가 블록 조각으로 막아야합니다. #s와 .s를 필수 패턴 (공백은 무엇이든 가능)으로 간주하면 위의 정확한 패턴이 하단 라인에서 일치하는 경우에만 19 점을 얻을 수 있습니다. 마찬가지로, 보드가이 패턴과 일치하면

   #
###.######
##.#######
#.########
.#########

하지만

    #
####.#####
###.######
##.#######
#.########
.#########

점수는 4입니다.

이 문제를 해결하려면 임의의 크기의 보드 (높이 20 셀 및 너비 10 셀 제외)를 고려하십시오. 같은 패턴으로 보드를 채점 할 수 있습니다. 예를 들어, 보드의 너비가 4 인 경우 이는 점수 3의 패턴입니다.

  #
##.#
#.##
.###

이것은 10 점의 패턴입니다.

   #
###.
##.#
#.##
.###
#.##
##.#
###.
##.#
#.##
.###

도전

임의 크기의 Tetris 보드의 최종 상태가 주어지면 위의 시스템을 사용하여 보드의 등급을 지정합니다.

직사각형 행렬에 대해 적절한 형식을 사용하여 보드를 가져올 수 있습니다. 여기서 모든 셀에는 두 개의 고유 한 값 (각각 비어있는 값과 채워진 값) 중 하나가 포함됩니다. 그리드가 유효한 Tetris 보드라고 가정 할 수 있습니다 (완전히 채워진 행 없음). 또한 그리드의 너비는 최소 2입니다.

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

테스트 케이스

혼동을 방지하기 위해 여기에서 테스트 케이스 O는 블록과 .빈 공간에 사용됩니다.

Input:
..O.O
OOOO.
OOO..
OO.OO
O.OOO
.OOOO
Output: 3

Input:
..
O.
.O
.O
O.
.O
O.
.O
Output: 4

Input:
.OOO
O.OO
OO.O
OO.O
OO.O
O.OO
.OOO
Output: 2 (any lines above the first non-conforming line are ignored;
           doesn't get 3 because 3rd line's hole is not capped)

Input:
OOO.
.OOO
O.OO
OO.O
OOO.
OO.O
O.OO
Output: 0 (Wrong starting hole)

Input:
.OOO
O.OO
OO.O
OOO.
Output: 0 (Wrong starting hole)

Input:
.OOO
.OOO
Output: 0 (Hole is not covered)

Input:
OOO...O..O
.OOOOOOOOO
O.OOOOOOOO
OO.OOOOOOO
OOO.OOOOOO
OOOO.OOOOO
OOOOO.OOOO
OOOOOO.OOO
OOOOOOO.OO
OOOOOOOO.O
OOOOOOOOO.
OOOOOOOO.O
OOOOOOO.OO
OOOOOO.OOO
OOOOO.OOOO
OOOO.OOOOO
OOO.OOOOOO
OO.OOOOOOO
O.OOOOOOOO
.OOOOOOOOO
Output: 19

답변

3 Arnauld Aug 18 2020 at 12:47

JavaScript (ES6), 84 바이트

1빈 공간 및 0블록에 대한 문자열 목록이 필요합니다.

f=(a,i=j=1<<a[k=0].length)=>(v='0b'+a.pop()+0)^i?v&i/k&&-1:1+f(a,i*=k=i&j?.5:i&2||k)

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

어떻게?

입력 배열의 각 문자열은 여분으로 채워 0지고 이진수로 해석됩니다. 변수가 j초기화되는 2**W경우, W기판의 폭이다. 패턴에서 예상되는 구멍 위치를 추적하기 위해 i초기화 된 비트 마스크를 사용합니다 j.

반복 할 때마다에 i를 곱합니다 k. k언제든지 (i & j) != 0(가장 왼쪽에서 (i & 2) != 0바운스 ) 또는 (가장 오른쪽에서 바운스 ) 값을 업데이트합니다 .

W = 5:

j = 0b100000

i = 0b100000 // -> set k to 1/2
i = 0b010000 // \
i = 0b001000 //  }-> leave k unchanged
i = 0b000100 // /
i = 0b000010 // -> set k to 2
i = 0b000100 // \
i = 0b001000 //  }-> leave k unchanged
i = 0b010000 // /
i = 0b100000 // -> set k to 1/2
...

댓글 작성

f = (                // f is a recursive function taking:
  a,                 //   a[] = input array
  i = j =            //   i = hole bit mask, initialized to ...
    1 << a[k = 0]    //   ... j = 2 ** W, where W is the width of the board
         .length     //   k = bit mask multiplier, initialized to 0
) =>                 //
( v =                // pop the last value from a[], append a '0' and interpret
  '0b' + a.pop() + 0 // it as a binary number saved in v
) ^ i ?              // if v is not equal to i:
  v & i / k          //   use the previous bit mask i / k to test whether there's
  && -1              //   a hole in v above the last hole of the pattern, in
                     //   which case we subtract 1 from the final result
:                    // else:
  1 +                //   add 1 to the final result
  f(                 //   do a recursive call:
    a,               //     pass a[] unchanged
    i *=             //     multiply i by:
      k =            //       the new value of k:
        i & j ?      //         if we've reached the leftmost side:
          .5         //           set k to 1/2
        :            //         else:
          i & 2      //           set k to 2 if we've reached the rightmost side,
          || k       //           or leave k unchanged otherwise
  )                  //   end of recursive call
3 Zgarb Aug 20 2020 at 04:54

Husk , 18 바이트

Lδ↑€…¢ŀT¹↑εΨ↑-↔m¥0

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

0-1 행렬을 사용합니다.

설명

이 프로그램 에는 세 가지 발생 이 있으며 수정 자 함수 δΨ. 기본적 으로는 단항 함수일 ↑α것으로 예상 α하고 목록을 α가져와 진실 값 을 반환하는 요소의 가장 긴 접두사를 반환합니다. Ψ↑α이 기대는 α바이너리, 그리고 요소의 긴 접두사 반환 할 수 x있는 α x y곳, truthy입니다 y다음 요소입니다. 바이너리 일 δ↑α것으로 예상하고 α하나가 아닌 두 개의 목록을 사용합니다. 요소가를 y충족 하는 두 번째 목록의 가장 긴 접두사를 반환합니다 α x y. 여기서는 x첫 번째 목록의 해당 요소입니다.

Input is a list of lists of integers.
Example: [[0,1,1],[1,0,1],[1,1,0],[1,0,1],[1,1,0],[0,0,1],[0,1,1]]

m     Map
 ¥0   indices where 0 occurs:
        [[1],[1,2],[3],[2],[3],[2],[1]]
↔     Reverse:
        [[1],[2],[3],[2],[3],[1,2],[1]]

 ↑    Take while
Ψ     this element and the next
  -   have nonempty set difference:
        [[1],[2],[3],[2],[3],[1,2]]

↑     Take while
 ε    this element is a singleton:
        [[1],[2],[3],[2],[3]]
      Call this list X.

ŀT¹   Indices of input transposed:
        [1,2,3]
¢     Cycle infinitely:
        [1,2,3,1,2,3,..]
…     Rangify:
        [1,2,3,2,1,2,3,2,1,..]
 ↑    Take from X while
δ     the corresponding integer in this list
  €   is an element of it:
        [[1],[2],[3],[2]]
L     Length: 4
2 Neil Aug 18 2020 at 19:06

차콜 , 52 바이트

WS⊞υι≔⮌υυP⪫υ¶W∧⁼.O⪫KD²↓ω⁼¹№§υⅉ.M✳⁻⁷⊗÷﹪ⅉ⊗⊖Lθ⊖Lθ≔ⅉθ⎚Iθ

온라인으로 시도하십시오! 링크는 자세한 코드 버전입니다. 줄 바꿈으로 끝나는 문자열 .O문자 목록으로 입력을 받습니다. 설명:

WS⊞υι

목록을 입력하십시오.

≔⮌υυ

목록을 뒤집습니다.

P⪫υ¶

커서를 이동하지 않고 목록을 인쇄합니다.

W∧

둘 다 반복하는 동안 ...

⁼.O⪫KD²↓ω

... 커서 아래에있는 문자는 a .이고 아래의 문자는 (목록이 반전 되었기 때문에) O이고 ...

⁼¹№§υⅉ.

... 현재 목록 줄에는 정확히 하나만 포함됩니다 ..

M✳⁻⁷⊗÷﹪ⅉ⊗⊖Lθ⊖Lθ

행에 따라 커서를 대각선 아래로 이동하고 오른쪽 또는 왼쪽으로 이동합니다.

≔ⅉθ⎚Iθ

첫 번째 유효하지 않은 행 인덱스 (0 인덱스이므로 유효한 행 수와 같음)를 캡처하고 캔버스를 지우고 문자열로 인쇄합니다.

2 xash Aug 18 2020 at 12:33

J , 57 42 바이트

차단 된 경우 0, 비어있는 경우 1을받습니다.

[:#.~(|.@$2^|@}:@i:@<:)/@$=2#.[*[+_1|.!.2]

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

작동 원리

[*[+_1|.!.2]

보드를 1 씩 아래로 이동합니다 (상단 지점이 계산되지 않도록 2 개가 상단에 밀려 들어갑니다.) 그런 다음 원래 보드에 추가하고 자신과 곱합니다. 이것은 기본적으로 다음과 같이 요약됩니다. 유효한 오픈 스팟은 1로 유지되고 유효하지 않은 스팟은 2가됩니다.

 (|.@$2^|@}:@i:@<:)/@$

치수가 주어지면 -x … x - 1너비에 대한 배타적 범위 ( 예 : 4 _3 _2 _1 0 1 2:)를 얻고 절대 값을 가져옵니다 3 2 1 0 1 2. 목록의 크기를 보드 높이로 조정하고 회전하여 시작하는 3이 마지막 행에 맞춰 2^x지고 목록이 정렬되도록 합니다.8 4 2 1 2 4 8 4 2…

 =2#.

행을 기본 2 숫자로 해석하고 지그재그 목록과 비교합니다.

 [:#.~

그리고 반사 기반 변환 을 통해 선행 1을 계산할 수 있으므로 선행 행이 유효합니다.

1 JonathanAllan Aug 19 2020 at 17:47

젤리 , 25 바이트

ZJŒḄṖṁLW€⁻"ⱮṚT€,Ḋ$ƊZḄCTḢ’

각 행이 음이 아닌 정수 (점수)를 생성하는 1s (비어 있음) 및 0s (채워짐) 목록 인 행 목록을 허용하는 모나 딕 링크 .

온라인으로 시도하십시오! 또는 테스트 스위트를 참조하십시오.

어떻게?

아래쪽에서 각 줄에 대해 예상되는 빈 인덱스 목록을 작성하고 두 목록, (a) 실제 빈 인덱스 및 (b) 대기열에서 제외 된 실제 빈 인덱스와 비교합니다. 그런 다음이 비교 결과를 처리하여 점수를 찾습니다.

ZJŒḄṖṁLW€⁻"ⱮṚT€,Ḋ$ƊZḄCTḢ’ - Link: list of lines, A
Z                         - transpose
 J                        - range of length     -> [1,2,...,w=#Columns]
  ŒḄ                      - bounce              -> [1,2,...,w-1,w,w-1,...,2,1]
    Ṗ                     - pop                 -> [1,2,...,w-1,w,w-1,...,2]
      L                   - length (A)          -> h=#Lines
     ṁ                    - mould like (repeat Ṗ result such that it is length h)
       W€                 - wrap each of these integers in a list (call this x)
                  Ɗ       - last three links as a monad - i.e. f(A):
            Ṛ             -   reverse (A)
             T€           -   for each (line) get the list of truthy ("empty") indices
                 $        -   last two links as a monad - i.e. f(z=that):
                Ḋ         -     dequeue (drop the leftmost)
               ,          -     (z) pair (that)
           Ɱ              - map across (the two results of f(A)) applying:
          "               -   (x) zip with (result) applying:
         ⁻                -     not equal?
                   Z      - transpose - now we have leading [0,1]'s for valid rows
                                        from the bottom up
                    Ḅ     - convert from binary - now leading 1s for valid rows
                     C    - complement (subtract (each) from one)
                      T   - truthy indices
                       Ḣ  - head
                        ’ - decrement
1 KevinCruijssen Aug 21 2020 at 10:39

05AB1E , 32 바이트

R©εDgݨû¨NèDU._ƶO®N>èX.__н*Θ}γнO

1과 0의 행렬로 입력합니다. 여기서 1은 빈 공간이고 0은 채워진 셀입니다.

온라인으로 시도하십시오. 또는 모든 테스트 케이스를 확인하십시오 .

설명:

R             # Reverse the rows of the (implicit) input-matrix
 ©            # Store it in variable `®` (without popping)
  ε           # Map over each row:
   Dg         #  Get the width of the matrix
     Ý        #  Push a list in the range [0,width]
      ¨       #  Remove the last element to change the range to [0,width-1]
       û      #  Palindromize it: [0,1,2,...,w-2,w-1,w-2,...,2,1,0]
        ¨     #  Remove the last value: [0,1,2,...,w-2,w-1,w-2,...,2,1]
         Nè   #  Index the map-index into this list
           DU #  Store a copy in variable `X`
    ._        #  Rotate the current row that many times to the left
      ƶ       #  Multiply each value by its 1-based index
       O      #  And sum this list
   ®          #  Push the reversed input-matrix again from variable `®`
    N>è       #  Index the map-index + 1 into this to get the next row
       X._    #  Also rotate it `X` amount of times towards the left
          _   #  Invert all booleans (1s becomes 0s, and vice-versa)
           н  #  And only leave the first value
   *          #  Multiply both together
    Θ         #  And check that it's equal to 1 (1 if 1; 0 otherwise)
  }γ          # After the map: split the list into groups of adjacent equivalent values
    н         # Only leave the first group
     O        # And take the sum of that
              # (after which it is output implicitly as result)