[프로그래머스] 공 이동 시뮬레이션

Chobby·2024년 3월 10일
1

Programmers

목록 보기
343/345

😀요점

  1. queries를 역순으로 풀이하며 코멘트를 참고
  2. 반환 값이 BigInt이므로 해당 설정없이 풀이한다면 7, 9번 테스트 케이스에서 오류 발생

😎풀이

function solution(n, m, x, y, queries) {
    // 방향 벡터를 설정합니다.
    const dx = [0, 0, 1, -1];
    const dy = [1, -1, 0, 0];

    // 다음 범위를 계산하는 함수를 정의합니다.
    // 이 함수는 현재 범위(s, e)와 이동량, 그리고 최대값을 인자로 받아
    // 이동 후의 범위를 반환합니다.
    function calNextRange(s, e, move, max) {
        // 이동 후의 시작점과 종료점을 계산합니다.
        const nextS = (s === 0 && move > 0) ? 0 : s + move;
        const nextE = (e === max - 1 && move < 0) ? max - 1 : e + move;

        // 시작점과 종료점이 모두 범위를 벗어난 경우
        if ((nextS < 0 || nextS >= max) && (nextE < 0 || nextE >= max)) {
            return [-1, -1];
        }
        // 시작점만 범위를 벗어난 경우
        if (nextS < 0 && nextE >= 0 && nextE < max) {
            return [0, nextE];
        }
        // 종료점만 범위를 벗어난 경우
        if (nextE >= max && nextS >= 0 && nextS < max) {
            return [nextS, max - 1];
        }
        // 시작점과 종료점이 모두 범위 내에 있는 경우
        return [nextS, nextE];
    }

    // 시작점과 종료점을 설정합니다.
    let [sx, ex, sy, ey] = [x, x, y, y];

    // 쿼리들을 역순으로 처리합니다.
    for (let i = queries.length - 1; i >= 0; i--) {
        const [dir, cnt] = queries[i];

        // y 좌표를 기준으로 처리합니다.
        if (dir === 0 || dir === 1) {
            const res = calNextRange(sy, ey, cnt * dy[dir], m);
            if (res[0] === -1) return 0;
            [sy, ey] = res;
        } 
        // x 좌표를 기준으로 처리합니다.
        else {
            const res = calNextRange(sx, ex, cnt * dx[dir], n);
            if (res[0] === -1) return 0;
            [sx, ex] = res;
        }
    }
    // x 범위와 y 범위에 속하는 점의 개수를 곱하여 반환합니다.
    return BigInt(ex - sx + 1) * BigInt(ey - sy + 1);
}
profile
내 지식을 공유할 수 있는 대담함

0개의 댓글