[프로그래머스] 프렌즈4블록(Python)

박현우·2021년 5월 26일
0

프로그래머스

목록 보기
31/34
post-custom-banner

문제

프렌즈4블록


문제 해설

주어진 요구사항에 따라 구현하는 문제입니다.

블록 삭제
일단 2 * 2모양의 블록을 살펴 본 뒤, 그 4개의 블록이 모두 일치한다면 블록이 사라집니다. 다만, 바로 사라지게 하는 것이 아니라 모든 board를 모두 탐색 한 뒤 삭제해야 합니다. 바로 삭제해버리면 원래는 4개였던 블록이 삭제 되지 않을 수도 있기 때문입니다.
ex)

그러므로 삭제할 좌표를 set에 저장한 뒤 중복을 제거(하던말던 상관없음)하고 한꺼번에 블록을 삭제해주는 것이 필요합니다.

블록 내리기
다음으로는 빈칸을 내려줘야 하는데, 한 열씩 보면서 내려주면 됩니다.
저같은 경우 새로운 큐를 생성한 뒤 열 하나를 확인하고 빈칸이 아니면 모두 큐에 담았습니다.
그리고 다시 큐에 담긴 요소들을 열에 채워줬습니다.


전체적인 구조는 다음과 같습니다.
1. 블록 삭제 -> 삭제된 블록 answer에 추가
2. 블록 내리기
3. 1,2 반복 -> 만약 삭제된 블록이 없으면 종료


풀이 코드

from collections import deque


def falling(m, n, board):
    for j in range(n):
        l = deque()
        for i in range(m - 1, -1, -1):
            # 빈칸이 아니면 큐에 모두 담는다
            if board[i][j] != "0":
                l.append(board[i][j])
        # 큐가 존재하면 빼서 담고 아니면 빈칸으로 만듬
        for i in range(m - 1, -1, -1):
            board[i][j] = l.popleft() if l else "0"
    return


def solution(m, n, board):
    for i in range(m):
        board[i] = list(map(str, board[i]))
    s = set()  # 지워지는 좌표들을 담을 set
    for i in range(m - 1):
        for j in range(n - 1):
            if board[i][j] == "0":
                continue
            priv = board[i][j]
            if (
                priv != board[i + 1][j]
                or priv != board[i][j + 1]
                or priv != board[i + 1][j + 1]
            ):
                continue
            s.add((i, j))
            s.add((i + 1, j))
            s.add((i, j + 1))
            s.add((i + 1, j + 1))
    # 만약 지워지는 블록이 없다면
    if not s:
        return 0
    # 블록 지우기
    for x, y in s:
        board[x][y] = "0"
    # 블록 떨어지기
    falling(m, n, board)
    return solution(m, n, board) + len(s)
post-custom-banner

0개의 댓글