[프로그래머스] 안전지대

이강혁·2023년 9월 15일
0

프로그래머스

목록 보기
9/82

https://school.programmers.co.kr/learn/courses/30/lessons/120866

문제 설명

다음 그림과 같이 지뢰가 있는 지역과 지뢰에 인접한 위, 아래, 좌, 우 대각선 칸을 모두 위험지역으로 분류합니다.

지뢰는 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 solution(board) {
var bombs = [];

let bx = [1, 1, 1, 0, -1, -1, -1, 0];
let by = [-1, 0, 1, 1, 1, 0, -1, -1];

//폭탄 좌표 찾기
board.forEach((x, idx, arr) => {
    x.forEach(((y, idy, x_axis) =>{
        if (y==1){
            bombs.push([idx, idy])
            arr[idx][idy] = 0;
        }
        else{
            arr[idx][idy] = 1;
        }
    }))
});


bombs.forEach(([x, y]) => {
    for(let i=0;i<8;i++){
        let dx=0, dy=0;
        if((x+bx[i])>=0&&(x+bx[i])<board.length) dx=x+bx[i]
        else continue;
        
        if((y+by[i])>=0&&(y+by[i])<board.length) dy=y+by[i]
        else continue;
        
        
        board[dx][dy] = 0;
    }
})
    
return board.reduce((prev, curr, idx, arr)=>{
    return prev + curr.reduce((a,b)=>a+b)
}, 0)    


}
  1. 폭탄이 있는 좌표를 찾아서 배열에 따로 좌표 저장, 폭탄이 있는 곳은 0으로 없는 곳은 1로 변경
  2. 폭탄 좌표를 돌면서 상화좌우대각선의 값을 0으로 변경
  3. 보드에 남은 1을 전부 더하면 안전한 칸의 개수

다른 풀이

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;
}

outside라는 상하좌우대각선이 담긴 배열에서 some 메소드를 통해 하나라도 1이 있다면 false를 하나도 1이 없다면 safezone에 1을 더해줌.

?. - 옵셔널 체이닝이라고 하는데 각 참조의 깊게 위치한 속성값까지 검증하는 연산자라고 하는데...... 잘 모르겠다.
!!self[oy+y]?.[ox+x]는 !!self[oy + y] && !!self[oy + y][ox + x] 라고 한다.
profile
사용자불량

0개의 댓글