def solution(board):
"""
블록 모양
- 3x2 블록 - 2x3 블록
top_left, top_mid, top_right top_left, top_right
btm_left, btm_mid, btm_right mid_left, mid_right
btm_left, btm_right
"""
"""검은 블록이 board[x][y]로 떨어질 수 있는지 확인"""
def check_falling(x, y):
for x_pos in range(0, x + 1):
if board[x_pos][y] != 0:
return False
return True
def check_two_three(x, y):
top_left, top_right = board[x][y], board[x][y + 1]
mid_left, mid_right = board[x + 1][y], board[x + 1][y + 1]
btm_left, btm_right = board[x + 2][y], board[x + 2][y + 1]
if (top_left == 0 and mid_left == 0) and (top_right == mid_right == btm_left == btm_right != 0):
# todo: mid_left 까지 블록이 떨어질 수 있는지 검사
if check_falling(x + 1, y):
board[x][y + 1] = board[x + 1][y + 1] = board[x + 2][y] = board[x + 2][y + 1] = 0
return True
elif (top_right == 0 and mid_right == 0) and (top_left == mid_left == btm_left == btm_right != 0):
# todo: mid_right 까지 블록이 떨어질 수 있는지 검사
if check_falling(x + 1, y + 1):
board[x][y] = board[x + 1][y] = board[x + 2][y] = board[x + 2][y + 1] = 0
return True
return False
def check_three_two(x, y):
top_left, top_mid, top_right = board[x][y], board[x][y + 1], board[x][y + 2]
btm_left, btm_mid, btm_right = board[x + 1][y], board[x + 1][y + 1], board[x + 1][y + 2]
if (top_left == 0 and top_right == 0) and (top_mid == btm_left == btm_mid == btm_right != 0):
# todo: top_left 와 top_right 까지 블록이 떨어질 수 있는지 검사
if check_falling(x, y) and check_falling(x, y + 2):
board[x][y + 1] = board[x + 1][y] = board[x + 1][y + 1] = board[x + 1][y + 2] = 0
return True
elif (top_left == 0 and top_mid == 0) and (top_right == btm_left == btm_mid == btm_right != 0):
# todo: top_left 와 top_mid 까지 블록이 떨어질 수 있는지 검사
if check_falling(x, y) and check_falling(x, y + 1):
board[x][y + 2] = board[x + 1][y] = board[x + 1][y + 1] = board[x + 1][y + 2] = 0
return True
elif (top_mid == 0 and top_right == 0) and (top_left == btm_left == btm_mid == btm_right != 0):
# todo: top_mid 와 top_right 까지 블록이 떨어질 수 있는지 검사
if check_falling(x, y + 1) and check_falling(x, y + 2):
board[x][y] = board[x + 1][y] = board[x + 1][y + 1] = board[x + 1][y + 2] = 0
return True
return False
answer = 0
while True:
remove = False
"""2x3 블록 단위 탐색"""
for i in range(len(board) - 2):
for j in range(len(board[0]) - 1):
if check_two_three(i, j):
remove = True
answer += 1
"""3x2 블록 단위 탐색"""
for i in range(len(board) - 1):
for j in range(len(board[0]) - 2):
if check_three_two(i, j):
remove = True
answer += 1
if not remove:
break
return answer
이 문제는 블록의 숫자를 구분할 필요가 없고, 블록이 제거되는 경우가 한정적이기 때문에 전체 board
를 2x3, 3x2 단위로 탐색하면서 블록이 제거될 수 있는지 확인했다.
블록이 제거될 수 있는 조건은 위의 조건 단 하나만 존재한다.
즉, 기존 블록들이 처음부터 겹쳐져서 2x3 또는 3x2 칸을 모두 채우고 있더라도 검은 블록이 없기 때문에 위의 조건을 충족하지 못한다.
또한 2x3 또는 3x2 탐색 단위 안에 블록이 겹쳐져 있고 검은 블록이 떨어져 두 블럭이 모두 제거 조건을 충족하여 두 개의 블록 둘 다 제거되야 하는지 고민할 수 있다. 하지만 조건을 읽어보면 그 블록
이라는 표현을 사용하는데, 오직 하나의 블록만이 제거됨을 의미한다.
결과적으로 이 문제는 탐색 단위내에 하나의 블록만 존재하고, 검은 블록을 통해 그 블록이 제거될 수 있는지 없는지만 판별하면 된다.