연습장/프로그래머스 문제풀이

[프로그래머스 Level 2] 프렌즈4블록 - JavaScript

Tesseractjh 2022. 6. 10. 00:10

🔗 문제 링크

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

 

코딩테스트 연습 - [1차] 프렌즈4블록

프렌즈4블록 블라인드 공채를 통과한 신입 사원 라이언은 신규 게임 개발 업무를 맡게 되었다. 이번에 출시할 게임 제목은 "프렌즈4블록". 같은 모양의 카카오프렌즈 블록이 2×2 형태로 4개가 붙

programmers.co.kr

✏️ 풀이

function solution(m, n, board) {
    board = board.map(row => [...row]);
    const offset = [[0, 0], [0, 1], [1, 0], [1, 1]];
    
    let count = 0;
    let flag = true;
    while (flag) {
        flag = false;
        const target = [];
        for (let i = 0; i < m - 1; i++) {
            for (let j = 0; j < n - 1; j++) {
                const blocks = offset.map(([dx, dy]) => board[i + dx][j + dy]);
                if (blocks.every(block => !!block && block === blocks[0])) {
                    offset.map(([dx, dy]) => target.push([i + dx, j + dy]));
                    flag = true;
                }
            }
        }
        target.forEach(([x, y]) => {
            const block = board[x][y];
            if (block) {
                board[x][y] = '';
                count++;
            }
        });
        for (let i = 0; i < n; i++) {
            const stack = [];
            for (let j = 0; j < m; j++) {
                const block = board[j][i];
                if (block) {
                    stack.push(block);
                }
            }
            for (let j = m - 1; j >= 0; j--) {
                if (stack.length) {
                    board[j][i] = stack.pop();
                } else {
                    board[j][i] = '';   
                }
            }
        }
    }
    return count;
}

보드 전체를 순회하면서 4개 블록에 해당하는 좌표를 모두 구한다. 중복이 있더라도 일단 target 배열에 모두 담는다. 그리고 나서 target을 순회하면서 해당 좌표의 블럭이 비어 있지 않을 때에만 그 블럭을 비우고 count를 증가시킨다. 이렇게 하면 중복 관계 없이 없어진 블록만큼만 count를 증가시킬 수 있다.

 

그 다음에는 보드를 세로 - 가로가 아닌, 가로 - 세로 순서로 순회하면서 세로 줄에 있는 모든 블록을 stack에 담는다. stack에 담긴 블록들은 다시 세로를 역순으로 순회하면서 보드를 채워넣는다. stack이 비면 그 뒤 좌표는 모두 비운다.

즉, 위에서 아래로 순회하면서 stack에 블록을 담고, 다시 아래에서 위로 순회하면서 stack에 담긴 블록을 pop해서 아래부터 채워넣고, 남는 자리는 모두 비워서 블록이 아래로 쌓이는 것을 구현한 것이다.

 

위 과정을 계속 반복하다가 처음에 4개짜리 같은 블록이 단 한 개도 없을 때 while문을 탈출한다.

while문을 탈출한 시점에서의 count가 구하고자 하는 답이 된다.