본문 바로가기

개발/알고리즘

[프로그래머스] 프렌즈4블록 Python 풀이

2018 KAKAO BLIND RECRUITMENT에 나온 기출 문제

문제 링크

https://school.programmers.co.kr/learn/courses/30/lessons/17679

 

프로그래머스

SW개발자를 위한 평가, 교육의 Total Solution을 제공하는 개발자 성장을 위한 베이스캠프

programmers.co.kr

 

풀이법

구현 문제이므로 문제 설명을 읽고 단계별로 함수 작성, 실행 순으로 풀었다.

1. 지워질 블록 찾기

2. 없으면 종료

3. 블록 지우기

4. 중력 적용

순서대로 구현하면 끝!

(말은 쉽지만 1시간 동안 구현했다..😭 실제 코테에 나온다면 시간을 많이 쓴 편이라 풀이 시간을 줄이는 연습을 해야 할 것 같다.)

 

주의할 점

* 입력값 board는 문자열 배열이므로 초반에 2차원 배열로 바꾸는 과정을 거쳤다.

 

풀면서 스멀 스멀 SWEA 냄새가 났는데 벽돌 깨기 문제와 유사한 것 같다.

예전에 풀어보긴 했지만 구현(특히 시뮬) 문제 풀기엔 SWEA 모의 SW 역량테스트가 좋은 것 같아서 다시 풀어봐야겠다는 생각이 들었다.

https://swexpertacademy.com/main/code/problem/problemDetail.do?contestProbId=AWXRQm6qfL0DFAUo

 

SW Expert Academy

SW 프로그래밍 역량 강화에 도움이 되는 다양한 학습 컨텐츠를 확인하세요!

swexpertacademy.com

 

정답 코드

* 문제 다 풀고 GPT한테 리팩토링 해달라고 했더니 주석도 넣어주고 깔끔하게 만들어줬다

def solution(m, n, board):
    answer = 0
    board = [list(row) for row in board]

    dx = [1, 1, 0]
    dy = [0, 1, 1]

    while True:
        to_remove = set()

        # 1. 지워질 블록 탐색
        for i in range(m - 1):
            for j in range(n - 1):
                base = board[i][j]
                if base == '':
                    continue
                if board[i + 1][j] == base and board[i][j + 1] == base and board[i + 1][j + 1] == base:
                    to_remove.update([(i, j), (i + 1, j), (i, j + 1), (i + 1, j + 1)])

        # 2. 더 이상 지울 게 없으면 종료
        if not to_remove:
            break

        # 3. 블록 제거
        for x, y in to_remove:
            if board[x][y] != '':
                board[x][y] = ''
                answer += 1

        # 4. 중력 적용
        for col in range(n):
            empty = []
            for row in range(m - 1, -1, -1):
                if board[row][col] == '':
                    empty.append(row)
                elif empty:
                    target = empty.pop(0)
                    board[target][col] = board[row][col]
                    board[row][col] = ''
                    empty.append(row)

    return answer