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

bkboy·2022년 6월 25일
0

문제

링크

풀이

// 하와 우, 대각선 아래를 판단
const judge = (board, i, j) => {
  if (
    board[i][j] === board[i + 1][j] &&
    board[i][j] === board[i][j + 1] &&
    board[i][j] === board[i + 1][j + 1]
  ) {
    return true;
  }
  return false;
};
function solution(m, n, board) {
  let answer = 0;

  // 보드를 2차원 배열로 만들어줌
  board = board.map((e) => e.split(""));

  // 배열에서 지워질 블록의 인덱스를 구한다.
  while (1) {
    const tmp = [];

    for (let i = 0; i < m - 1; i++) {
      for (let j = 0; j < n - 1; j++) {
        if (board[i][j] && judge(board, i, j)) {
          tmp.push([i, j]);
        }
      }
    }

    // 답, 더이상 사라지는 노드가 없다면!
    // 현재 board의 0를 판단, 이중 for문을 사용하지 않는 방법.
    if (!tmp.length) {
      return [].concat(...board).filter((e) => !e).length;
    }
    //  배열에서 지워질 블록을 0으로 바꾼다.
    for (let i = 0; i < tmp.length; i++) {
      const [col, row] = tmp[i];
      board[col][row] = 0;
      board[col][row + 1] = 0;
      board[col + 1][row] = 0;
      board[col + 1][row + 1] = 0;
    }

    // 위에서 블록을 당겨오기, 행을 기준으로 열을 살펴야한다.
    for (let i = m - 1; i > 0; i--) {
      // 해당 행에 부서진게 없으면, 다음행으로
      if (!board[i].some((v) => !v)) continue;

      // 있다면, 열을 살핌
      for (let j = 0; j < n; j++) {
        // 시작점이 i임으로 i 한칸 위부터
        for (let k = i - 1; k >= 0 && !board[i][j]; k--) {
          if (board[k][j]) {
            board[i][j] = board[k][j];
            board[k][j] = 0;

            // 하나를 땡겨오면 그 뒤론 다른 열을 봐야함
            break;
          }
        }
      }
    }
  }
  return answer;
}

위에 블록에서 당겨오는 로직이 꽤 복잡하다.
i는 행을 아래부터, j는 열을 위부터, k는 행을 i행 하나 위부터 살피고있다는 것을 알면 이해하는데 도움이 된다.

그림을 그려보자.

profile
음악하는 개발자

0개의 댓글