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

Kyle·2020년 12월 28일
0

problem solving

목록 보기
20/36

문제

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

해결방법

2*2형태를 square라고 하겠다.

  1. board를 2차원 배열로 만들어서 요소 하나하나 확인한다.
    1-1. square를 검사한다.
    1-2. square인 index를 row와 column을 &로 구분해서 문자열로 set(indexSet)에 저장한다.
    (- set은 자동으로 중복을 제거해 주기때문에 문자열로 넣는다.
    - row,column이 10의 자리가 넘어갈 수있기 때문에 &로 둘을 구분해 주었다.)

  2. indexSet을 돌면서 square인 값들을 0으로 바꿔준다.
    2-1. indexSet 초기화

  3. 값이 0으로 된 부분 위에 있는 값들을 아래로 끌고 내려온다.

  4. 1,2,3을 반복하며 square인 인덱스가 없으면 break해준다.

reorderBoard: 0으로 변한 부분의 위 부분을 끌고 내려오기

예시로 설명하겠습니다.
ex)
[['A','B','C'],
[ 0, 0, 'A'],
[ 0, 0, 'A']]

  • 위의 배열을 행으로 이뤄진 배열로 바꿀 것입니다.
  1. 배열로 바꿀 때 0인 부분은 넘기고 쌓아(push) 줍니다.
    [['A'],
    ['B'],
    ['C','A','A']]

  2. 뒤의 빈칸 만큼 0을 넣어줍니다.(unshift)
    [[0,0,'A'],
    [0,0,'B'],
    ['C','A','A']]

  3. 이제 위의 배열을 열로 다시 바꿔주면 아래로 쌓인 배열이 됩니다. newBoard[col][row] = tmpBoard[row][col];
    [[0,0,'C'],
    [0,0,'A'],
    ['A','B','A']]

code

function solution(m, n, board) {
  board = board.map((v) => v.split(""));
  var answer = 0;
  while (true) {
    let indexSet = new Set();
    for (let i = 0; i < m - 1; i++) {
      for (let j = 0; j < n - 1; j++) {
        const startIndex = [i, j];
        if (board[i][j] === 0) continue;
        else if (checkSquare(board, startIndex)) {
          getSquareIndex(indexSet, startIndex);
        }
      }
    }
    if (indexSet.size === 0) break;
    else answer += indexSet.size;

    indexSet.forEach((v) => {
      const [row, col] = v.split("&");
      board[row][col] = 0;
    });

    indexSet.clear();

    board = reorderBoard(m, n, board);
  }
  return answer;
}

function checkSquare(board, startIndex) {
  const [row, col] = startIndex;
  return (
    board[row][col] === board[row + 1][col] &&
    board[row][col] === board[row][col + 1] &&
    board[row][col] === board[row + 1][col + 1]
  );
}
function getSquareIndex(indexSet, startIndex) {
  const [row, col] = startIndex;
  indexSet.add(`${row}&${col}`);
  indexSet.add(`${row + 1}&${col}`);
  indexSet.add(`${row}&${col + 1}`);
  indexSet.add(`${row + 1}&${col + 1}`);
  return indexSet;
}

function reorderBoard(m, n, board) {
  let newBoard = Array.from({ length: m }, () => new Array(n));
  const tmpBoard = [];
  for (let col = 0; col < n; col++) {
    let colArr = [];
    for (let row = 0; row < m; row++) {
      if (board[row][col] !== 0) colArr.push(board[row][col]);
    }
    while (colArr.length !== m) {
      colArr.unshift(0);
    }
    tmpBoard.push(colArr);
  }
  for (let row = 0; row < n; row++) {
    for (let col = 0; col < m; col++) {
      newBoard[col][row] = tmpBoard[row][col];
    }
  }
  return newBoard;
}

마무리

set에 저장한 인덱스를 처음에는 &같은 구분자? 구분체크? 없이 문자열로 바꿔서 넣어주기만 했다.

10의 자리로 넘어가면 index가 뒤죽박죽이 돼 해결이 되지 않았다.

계속 코드만 보면서 해결하려고 했지만 실패했었다. 그래서 왜 시간 초과가 나지 하면서 배열의 길이를 길게 해서 디버깅하는데 이 오류를 발견하게 됐다.

코드만 보면 이미 갇힌 생각에 쉽게 빠져나올 수 없는 것같다.
코드를 보다 못 찾겠으면 예시를 생각해서 테스트해보는 것이 큰 도움이 된다는 것을 배웠다.

profile
Kyle 발전기

0개의 댓글