😈 안전지대
📗 문제 설명
다음 그림과 같이 지뢰가 있는 지역과 지뢰에 인접한 위, 아래, 좌, 우 대각선 칸을 모두 위험지역으로 분류합니다.
지뢰는 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합니다.
💎나의 풀이
board와 같은 크기의 배열의 복사본을 하나 만들어서 위험지역을 표시 할 생각이다.
// 안전 지역을 표시할 board와 같은 배열
const arr = Array.from({ length: board.length }, () => Array.from({ length: board.length }, () => 0));
이제 board 전체를 순회하여 board에 있는 1들을 탐색 해야한다.
그리고 만든 복사본에 똑같이 그려넣어 주자.
for (let i = 0; i < board.length; i++) {
for (let j = 0; j < board.length; j++) {
if (board[i][j] === 1) {
arr[i][j] = 1;
}
}
}
이제 매개 변수에서 1들을 찾아내어 복사본에 붙여 넣을 것이다.
이제 나머지 0들을 찾아내어서 주변에 1 또는 지뢰지역(결국은 셀이 1인지역) 을 찾아내야 한다.
그러기 위해선 8방향 검사가 필요하다.
** 9개의 셀을 검사하는 것이 아닌 8방향을 검사하는 것은 이미 위에서 1은 찾아놓았기 때문에 8방향 검사만 하면 된다.
8방향 검사에 필요한 좌표 변수들을 만들어주자.
// 지뢰 위치 이외에 8방향 위험지역 좌표
const x = [-1, -1, -1, 0, 0, 1, 1, 1];
const y = [-1, 0, 1, -1, 1, -1, 0, 1];
이제 지뢰를 기준으로 이 좌표에 1을 만들어 줄것이다.
8방향 검사이기 때문에 0 ~ 7 까지의 반복만 돌리자.
반복 문을 돌리기전에 이 구역이 안전한지 위험한지 판별해주는 스위치 하나 만들어 줘야 후에 안전지역 검사에 필요할 것 같다.
주변 셀이 위험지역으로 판별나면 반복문을 멈춰주자.
주변 셀이 안전하다면 복사본에 0 을 끼워 넣어주자.
우리는 안전지대의 갯수만 파악해주면 되니 카운트 변수 하나 만들어주고 거기에 0을 끼어 넣어줄때마다 카운트 업 시키면 될 것같다.
// 안전지역 저장 할 변수
let safe = 0;
// 위험지역이 아닌 구역(셀이 0 인 구역)일 경우 주변 8방향 셀 검사
let isSafe = true;
// 8방향 검사
for (let k = 0; k < 8; k++) {
const ni = i + x[k];
const nj = j + y[k];
if (ni >= 0 && ni < board.length && nj >= 0 && nj < board.length && board[ni][nj] === 1) {
isSafe = false;
break;
}
}
if (isSafe) {
arr[i][j] = 0;
safe++;
}
밑에는 완성한 코드다.
const solution = board => {
// 지뢰 위치 이외에 8방향 위험지역 좌표
const x = [-1, -1, -1, 0, 0, 1, 1, 1];
const y = [-1, 0, 1, -1, 1, -1, 0, 1];
// 안전지역 저장 할 변수
let safe = 0;
// 안전 지역을 표시할 board와 같은 배열
const arr = Array.from({ length: board.length }, () => Array.from({ length: board.length }, () => 0));
for (let i = 0; i < board.length; i++) {
for (let j = 0; j < board.length; j++) {
// 지뢰가 있는 구역(셀이 1인 구역)
if (board[i][j] === 1) {
// 위험지역을 1로 표시
arr[i][j] = 1;
} else {
// 위험지역이 아닌 구역(셀이 0 인 구역)일 경우 주변 8방향 셀 검사
let isSafe = true;
// 8방향 검사
for (let k = 0; k < 8; k++) {
const ni = i + x[k];
const nj = j + y[k];
// 주변 셀이 배열 범위 내에 있고, 주변 셀이 위험지역 일 경우
if (ni >= 0 && ni < board.length && nj >= 0 && nj < board.length && board[ni][nj] === 1) {
// 위험 지역임을 체크 하고 종료
isSafe = false;
break;
}
}
// 주변 셀이 안전 할 경우
if (isSafe) {
// 새로운 배열에서 해당위치를 0으로 표시
arr[i][j] = 0;
// 안전지역 증가
safe++;
}
}
}
}
return safe;
}
머리아프다.
'코딩테스트 > 프로그래머스' 카테고리의 다른 글
[프로그래머스 😈] JavaScript 2차원으로 만들기 (0) | 2023.10.26 |
---|---|
[프로그래머스 😈] JavaScript 최빈값 구하기 (0) | 2023.10.25 |
[프로그래머스 😈] JavaScript OX퀴즈 (0) | 2023.10.24 |
[프로그래머스 😈] JavaScript 배열의 길이에 따라 다른 연산하기 (0) | 2023.10.24 |
[프로그래머스 😈] JavaScript 저주의 숫자 (0) | 2023.10.24 |