백준 14503번 로봇청소기 - JS

김민찬·2022년 12월 11일
0

알고리즘

목록 보기
9/15
post-thumbnail

소감

  • 문제가 이해가 잘 안되어서 오래걸린 문제다 (약 10시간)
  • 코드가 잘못된 것을 깨달았을 때 싹 지우고 처음부터 다시푸는것도 나쁘지 않다.
  • while문에 label을 처음 써봤는데 생각보다 가독성이 떨어지지는 않는다. 오히려 if문을 줄일 수 있어서 가독성이 올라간 것 같기도?
const fs = require('fs');
const input = fs.readFileSync('/dev/stdin').toString().trim().split('\n');

const tranformData = data => data.split(' ').map(Number);

const direction = [[-1, 0], [0, 1], [1, 0], [0, -1]];

const solution = () => {
    const [areaSize, inital, ...area] = input.map(tranformData);
    const [N, M] = areaSize;
    
    let count = 0;
    const getCleaning = (location) => {
        const queue = [];
        
        queue.push(location);

        outer: while (queue.length) {
            let [r, c, d] = queue.shift();

            if (!area[r][c]) {
                count++
                area[r][c] = 2;
            }

            // 한 방향씩 돌면서 확인
            for (let i = 0; i < 4; i++) {
                d = d - 1 < 0 ? 3 : d - 1;
                const [dR, dC] = direction[d];
                const [nextR, nextC] = [r + dR, c + dC];

                if (!area[nextR][nextC]) {
                    queue.push([nextR, nextC, d]);
                    continue outer;
                }
            }

            // 네 방향 모두 청소되어있는 경우
            // 뒤 방향
            const [bR, bC] = direction[(d + 2) % 4];
            const [backR, backC] = [r + bR, c + bC];

            // 뒤가 벽일 경우 멈추기
            if (backC <= 0 || backC >= M || backR <= 0 || backR >= N || area[backR][backC] === 1) {
                break;
            }

            queue.push([backR, backC, d])
        }
    }
    getCleaning(inital);


    console.log(count);
}

solution();

추가

  • 2차 풀이
  • M, N이 필요 없어서 삭제
const fs = require('fs');
const input = fs.readFileSync('/dev/stdin').toString().trim().split('\n');

const tranformData = data => data.split(' ').map(Number);

const direction = [[-1, 0], [0, 1], [1, 0], [0, -1]];

const solution = () => {
    const [_, inital, ...area] = input.map(tranformData);
    
    let count = 0;
    const getCleaning = (location) => {
        const queue = [];
        
        queue.push(location);

        outer: while (queue.length) {
            let [r, c, d] = queue.shift();

            if (!area[r][c]) {
                count++
                area[r][c] = 2;
            }

            // 한 방향씩 돌면서 확인
            for (let i = 0; i < 4; i++) {
                d = d - 1 < 0 ? 3 : d - 1;
                const [dR, dC] = direction[d];
                const [nextR, nextC] = [r + dR, c + dC];

                if (!area[nextR][nextC]) {
                    queue.push([nextR, nextC, d]);
                    continue outer;
                }
            }

            // 네 방향 모두 청소되어있는 경우
            // 뒤 방향
            const [bR, bC] = direction[(d + 2) % 4];
            const [backR, backC] = [r + bR, c + bC];

            // 뒤가 벽일 경우 멈추기
            if (area[backR][backC] === 1) {
                break;
            }

            queue.push([backR, backC, d])
        }
    }
    getCleaning(inital);


    console.log(count);
}

solution();
profile
두려움 없이

0개의 댓글