[기초 Lv.0] 안전지대

oaksusu·2024년 3월 27일
0
post-thumbnail

오답노트 23번

1. 문제 (링크) :

다음 그림과 같이 지뢰가 있는 지역과 지뢰에 인접한 위, 아래, 좌, 우 대각선 칸을 모두 위험지역으로 분류합니다.
지뢰는 2차원 배열 board에 1로 표시되어 있고 board에는 지뢰가 매설 된 지역 1과, 지뢰가 없는 지역 0만 존재합니다.
지뢰가 매설된 지역의 지도 board가 매개변수로 주어질 때, 안전한 지역의 칸 수를 return하도록 solution 함수를 완성해주세요.

2. 내가 푼 방법 :

[처음 오답 풀이]
1. 우선, 2차원 배열을 순회하면서 1이 든 요소를 찾음
2. 해당 요소의 좌우상하대각선방향의 위치를 문자열로 만들고,
해당 문자열들을 담은 배열을 순회하면서 2차원 배열의 범위를 벗어난 값들을 (마이너스가 들어간 숫자 혹은 배열의 인덱스보다 커진 값이 들어간 경우)
제외한 나머지들을 Set객체로 선언한 변수에 담아줌
(그러면 Set객체 특성상 중복된 값은 알아서 제외시킴)

위와 같은 의도는 문제풀이상 오류는 아니였지만,
내가 만들었던 조건이 틀렸었음
(i+1 < length) && (j+1 < length) 이 조건은 무조건 false가 되므로
i+1한 값이 length를 넘어가는 문자열이 담긴 것을 필터링해줬어야함!
즉 !ele.includes(${length}) 처럼 문자열안에 length가 들어가있는지를 점검하면 됐음

function solution(board) {
    const length = board.length;
    const total = Math.pow(board.length,2);
    const dangerList = new Set();
    
    for (let i = 0; i < length; i++) {
        for (let j = 0; j < length; j++) {
            if (!!board[i][j]) {
                [`${i-1}+${j-1}`,`${i-1}+${j}`,`${i-1}+${j+1}`,`${i}+${j-1}`,`${i}+${j}`,`${i}+${j+1}`,`${i+1}+${j-1}`,`${i+1}+${j}`,`${i+1}+${j+1}`].map((ele) =>{
                    if (!ele.includes('-') && (i+1 < length) && (j+1 < length)) {
                        dangerList.add(ele);
                        console.log(ele)
                    }
                })
            }
        }
    }
    return total - dangerList.size
}

[힌트를 통해 반례를 추가해서 해결한 오답풀이]

function solution(board) {
    const length = board.length;
    const total = Math.pow(board.length,2);
    const dangerList = new Set();
    
    for (let i = 0; i < length; i++) {
        for (let j = 0; j < length; j++) {
            if (!!board[i][j]) {
                [`${i-1}+${j-1}`,`${i-1}+${j}`,`${i-1}+${j+1}`,`${i}+${j-1}`,`${i}+${j}`,`${i}+${j+1}`,`${i+1}+${j-1}`,`${i+1}+${j}`,`${i+1}+${j+1}`].map((ele) =>{
                    if (!ele.includes('-') && !ele.includes(`${length}`)) {
                        dangerList.add(ele);
                    }
                })
            }
        }
    }
    return total - dangerList.size
}

결국엔 문제를 풀긴했지만 너무 하드코딩으로 푼것같아서
다른 사람의 풀이 중에 나와는 반대로
위험하지 않는 지역을 찾아서 해결한 풀이가 있었다.

3. 괜찮아 보였던 풀이 방법 (참고할 만한 풀이):

[다른 사람의 풀이]

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

[참고해서 풀어본 내 풀이]

function solution(board) {
    const range = [[-1,-1],[0,-1],[1,-1],[-1,0],[0,0],[1,0],[-1,1],[0,1],[1,1]];
    let safe = 0;
    
    board.forEach((ele, eleIdx) => {
        ele.forEach((innerEle, innerEleIdx) => {
            const isSafe = range.some(([x,y]) => !!board[eleIdx+x]?.[innerEleIdx+y]);
            !isSafe && safe++
        })
    })
    return safe
}
profile
삐약

0개의 댓글