문제 설명
제한사항
다음 그림과 같이 지뢰가 있는 지역과 지뢰에 인접한 위, 아래, 좌, 우 대각선 칸을 모두 위험지역으로 분류합니다.
지뢰는 2차원 배열 board에 1로 표시되어 있고 board에는 지뢰가 매설 된 지역 1과, 지뢰가 없는 지역 0만 존재합니다.
지뢰가 매설된 지역의 지도 board가 매개변수로 주어질 때, 안전한 지역의 칸 수를 return하도록 solution 함수를 완성해주세요.
제한사항
- board는 n * n 배열입니다.
- 1 ≤ n ≤ 100
- 지뢰는 1로 표시되어 있습니다.
- board에는 지뢰가 있는 지역 1과 지뢰가 없는 지역 0만 존재합니다.
입출력 예
board | result |
[[0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 1, 0, 0], [0, 0, 0, 0, 0]] | 16 |
[[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]] | 13 |
[[1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1]] | 0 |
입출력 예 설명
입출력 예 #1
- (3, 2)에 지뢰가 있으므로 지뢰가 있는 지역과 지뢰와 인접한 위, 아래, 좌, 우, 대각선 총 8칸은 위험지역입니다. 따라서 16을 return합니다.
입출력 예 #2
- (3, 2), (3, 3)에 지뢰가 있으므로 지뢰가 있는 지역과 지뢰와 인접한 위, 아래, 좌, 우, 대각선은 위험지역입니다. 따라서 위험지역을 제외한 칸 수 13을 return합니다.
입출력 예 #3
- 모든 지역에 지뢰가 있으므로 안전지역은 없습니다. 따라서 0을 return합니다.
function isValidIndex(board, index) {
// 빈칸이면 true, 아니라면 false return
return board[index] === 0;
}
function solution(board) {
const ROW = board.length;
const COL = board[0].length;
board = board.flat();
let bombIndexList = [];
board.map((el, idx) => {
if(el === 1) bombIndexList.push(idx);
});
// 전부 다 지뢰인 경우
if(bombIndexList.length === ROW * COL) return 0;
// 지뢰가 없는 경우
if(bombIndexList.length === 0) return ROW * COL;
// 그 외
for(let bombIndex of bombIndexList) {
let dangerIndexList = [bombIndex];
// (지뢰 - 1) 인덱스가 마지막 열의 인덱스가 아닐 경우
// = (지뢰 - 1)의 인덱스가 이전의 행으로 넘어가지 않을 경우
if((bombIndex - 1) % COL !== (COL - 1)) dangerIndexList.push(bombIndex - 1);
// (지뢰 + 1) 인덱스가 첫번째 열의 인덱스가 아닐 경우
// = (지뢰 + 1)의 인덱스가 다음 행으로 넘어가지 않을 경우
if((bombIndex + 1) % COL !== 0) dangerIndexList.push(bombIndex + 1);
dangerIndexList.map(el => {
dangerIndexList.push(el - COL, el + COL);
});
dangerIndexList = dangerIndexList.filter(el => isValidIndex(board, el));
dangerIndexList.map(el => {
board[el] = 'X';
});
}
return board.filter(el => el === 0).length;
}
보통 이런문제를 풀게되면 2차원 배열을 반복문을 돌면서 지뢰가 있는 칸일경우 다시 이중 반복문을 통해 주변 타일을 검사하게 된다. 그런데 그렇게 되면 반복문의 depth가 깊어져 보기싫어져서 1차원 배열로 flat 해준후에 풀이를 했다.
이 풀이에서 가장 중요한 부분은 체크를 할 때 인덱스의 overflow나 underflow의 체크를 하는 것이다.
지뢰의 양옆을 체크할때, 왼쪽을 체크할 경우는 2차원 배열에서의 맨 처음 열보다 더 왼쪽으로 가면 안되고,
오른쪽을 체크할 경우에는 2차원 배열에서의 맨 마지막 열보다 더 오른쪽으로 가면 안된다.
위의 경우는 맨 처음 열에 지뢰가 왔을 경우나 맨 마지막 열에 지뢰가 왔을 경우에 해당이 된다.
따라서 if 분기문을 통해 그 두 가지만 따로 빼서 체크해주었다.
'PS > Programmers' 카테고리의 다른 글
Programmers / Level 0 / 다항식 더하기 / JS (0) | 2022.10.24 |
---|---|
Programmers / Level 0 / 분수의 덧셈 / JS (0) | 2022.10.24 |
Programmers / Level 0 / 겹치는 선분의 길이 / JS (0) | 2022.10.24 |
Programmers / Level 0 / 평행 / JS (0) | 2022.10.19 |