Level2 - 빛의 경로 사이클

손대중·2022년 5월 18일
0

문제 설명 및 링크

https://programmers.co.kr/learn/courses/30/lessons/86052?language=javascript#

나의 풀이

아래 사항만 명심하고 풀면 쉽게 풀릴 수 있다.

  • 각 격자는 4가지 방향성 (left, right, up, down) 을 갖고, 각 격자 & 방향은 하나의 사이클만 지나감

즉 한번 지나간 격자 & 방향은 두번 살펴볼 필요 없다.

먼저 x, y, arrow 조합으로 map 을 만든 이후 map 을 돌면서 현재 이 격자 & 방향을 지나가는 사이클을 조사한다. (이미 지나간 자리는 skip)

사이클 조사시에는 해당 사이클을 지나가는 격자 & 방향 map 에 true 로 세팅한다.

말이 어렵네. 코드가 더 쉬움.

코드

모든 프로그래머스 문제 관련 코드들은 GitHub 링크 에 있음.

// 싸이클을 돌면서 지나간 자리는 checkMap 에 추가
const getCycleLength = (grid, target, checkMap) => {
    let count = 0;

    while (!checkMap[`${target.x}_${target.y}_${target.arrow}`]) {
        checkMap[`${target.x}_${target.y}_${target.arrow}`] = true;

        let next = {...target};

        if (target.arrow === 'left') {
            next.x = next.x === 0 ? grid[0].length - 1 : next.x - 1;

            if (grid[next.y][next.x] === 'L') {
                next.arrow = 'down';
            } else if (grid[next.y][next.x] === 'R') {
                next.arrow = 'up';
            }
        } else if (target.arrow === 'right') {
            next.x = next.x === grid[0].length - 1 ? 0 : next.x + 1;

            if (grid[next.y][next.x] === 'L') {
                next.arrow = 'up';
            } else if (grid[next.y][next.x] === 'R') {
                next.arrow = 'down';
            }
        } else if (target.arrow === 'up') {
            next.y = next.y === 0 ? grid.length - 1 : next.y - 1;

            if (grid[next.y][next.x] === 'L') {
                next.arrow = 'left';
            } else if (grid[next.y][next.x] === 'R') {
                next.arrow = 'right';
            }
        } else if (target.arrow === 'down') {
            next.y = next.y === grid.length - 1 ? 0 : next.y + 1;

            if (grid[next.y][next.x] === 'L') {
                next.arrow = 'right';
            } else if (grid[next.y][next.x] === 'R') {
                next.arrow = 'left';
            }
        }

        target = next;

        count++;
    }
    
    return count;
};

function solution(grid) {
    let result = [];
    
    // 하나의 격자 & 방향 (left, right, up, down) 을 조합하여 map 초기화
    const checkMap = {};
    
    for (let x = 0; x < grid[0].length; x++) {
        for (let y = 0; y < grid.length; y++) {
            checkMap[`${x}_${y}_left`] = false;
            checkMap[`${x}_${y}_right`] = false;
            checkMap[`${x}_${y}_up`] = false;
            checkMap[`${x}_${y}_down`] = false;
        }
    }
    
    // map 을 돌면서 격자 & 방향 을 지나는 싸이클 조사 (이미 지나갔으면 skip)
    for (let key in checkMap) {
        if (checkMap[key]) {
            continue;
        }
        
        const arr = key.split('_');
        const target = {x: Number(arr[0]), y: Number(arr[1]), arrow: arr[2]};
        result.push(getCycleLength(grid, target, checkMap));
    }
    
    return result.sort((r1, r2) => r1 - r2);
}

0개의 댓글