본문 바로가기
Research/Coding Test

프로그래머스_lv0_안전지대

by RIEM 2023. 11. 17.

문제 해결 방법

안전지대 문제의 핵심은 폭탄을 기준으로 이전, 현재, 다음 요소를 안전지대에서 해제하는 것이다. 이는 현재 배열 뿐만 아니라 전후 배열도 마찬가지다.

그래서 직관적으로 전, 현, 다음 요소를 안전지대의 상태인 0에서 비안전지대(내가 정함) 상태 2로 바꿔주었다. 그리고 2차 forEach 반복문에서 forEach의 두 번째 매개변수로 idx을 사용할 수 있기에 이를 사용하여 전후 배열에 접근하여 동일하게 상태 변환 작업을 해주었다.

function solution(board) {
  board.forEach((vertEl, vertIdx) => {
    vertEl.forEach((horEl, horIdx) => {
      // 폭탄 발견 시
      if (horEl === 1) {
        // 같은 hor, 이전 요소
        if (board[vertIdx][horIdx - 1] === 0) {
          board[vertIdx][horIdx - 1] = 2;
        }
        // 같은 hor, 다음 요소
        if (board[vertIdx][horIdx + 1] === 0) {
          board[vertIdx][horIdx + 1] = 2;
        }

        // 이전 horizontal
        if (board[vertIdx - 1]) {
          // 이전 hor, 이전 요소
          if (board[vertIdx - 1][horIdx - 1] === 0) {
            board[vertIdx - 1][horIdx - 1] = 2;
          }

          // 이전 hor, 같은 요소
          if (board[vertIdx - 1][horIdx] === 0) {
            board[vertIdx - 1][horIdx] = 2;
          }

          // 이전 hor, 다음 요소
          if (board[vertIdx - 1][horIdx + 1] === 0) {
            board[vertIdx - 1][horIdx + 1] = 2;
          }
        }

        // 다음 horizontal
        if (board[vertIdx + 1]) {
          // 다음 hor, 이전 요소
          if (board[vertIdx + 1][horIdx - 1] === 0) {
            board[vertIdx + 1][horIdx - 1] = 2;
          }

          // 다음 hor, 같은 요소
          if (board[vertIdx + 1][horIdx] === 0) {
            board[vertIdx + 1][horIdx] = 2;
          }

          // 다음 hor, 다음 요소
          if (board[vertIdx + 1][horIdx + 1] === 0) {
            board[vertIdx + 1][horIdx + 1] = 2;
          }
        }
      }
    });
  });

  const filteredFlatArr = [].concat(...board).filter((el) => el === 0);

  return filteredFlatArr.length;
}

console.log(
  solution([
    [0, 0, 0, 0, 0],
    [0, 0, 0, 0, 0],
    [0, 0, 0, 0, 0],
    [0, 0, 1, 1, 0],
    [0, 0, 0, 0, 0],
  ]),
);

만들고 보니 직관적이긴 한데 다소 하드코딩한 느낌이 들어서 조금 아쉽다는 생각을 가지고 있다.

타인의 풀이

function solution(board) {

    let outside = [[-1,0], [-1,-1], [-1,1], [0,-1],[0,1],[1,0], [1,-1], [1,1]];
    let safezone = 0;

    board.forEach((row, y, self) => row.forEach((it, x) => {
        if (it === 1) return false;
        return outside.some(([oy, ox]) => !!self[oy + y]?.[ox + x])
               ? false : safezone++;
    }));

    return safezone;
}

이분도 forEach로 2차 반복문을 사용했는데, 안전지대면 그냥 넘어가고 그렇지 않은 경우 조건문으로 처리를 해주는 방식으로 접근했다.

조건문은 배열의 외각에 있는 경우의 수 배열을 some으로 테스트하고 그런 경우 false 그렇지 않으면 더하는 방식으로 문제를 해결했다. 

이 부분은 잘 이해가 안되는데 some, 삼항 연산자로 깔끔하게 표현하면 코드를 줄일 수 있을 수도 있겠다는 생각이 들었다.

https://school.programmers.co.kr/learn/courses/30/lessons/120866/solution_groups?language=javascript

'Research > Coding Test' 카테고리의 다른 글

해시_전화번호 목록  (0) 2023.11.18
해시_폰켓몬  (0) 2023.11.17
해시_완주하지 못한 선수  (0) 2023.11.16
Leetcode_bubbleSort_Height Checker  (0) 2023.04.19
HackerRank_Apple and Orange  (0) 2023.04.12

댓글