프로그래머스 택배 배달과 수거하기 JavaScript

2023년 1월 9일

프로그래머스 택배 배달과 수거하기

문제 풀이

상당히 오래 걸린 문제였다.
물류창고에서 n개의 집에 택배를 배달하고 빈 택배 상자를 수거할 때 최소 거리로 이동하는 문제이며,
매개변수로 (cap: 실을 수 있는 최대 택배 상자 개수, n: 집의 개수, deliveries: 집에 배달할 택배 상자 개수 리스트, pickups: 집에서 수가할 택배 상자 개수 리스트)가 주어진다.

스택을 이용해 deliveriespickups 모두 빈 배열이 될 때까지 while을 돌린다.
deliveriespickups 를 따로 계산할 거기에 deliveryCnt, pickupCnt 를 선언한다. 이 변수들은 각각 트럭이 배달, 수거할 수 있는 여유분이다. 0 이되면 더 이상 배달하거나 수거할 수 없다.

트럭의 이동하는 최소 거리를 구하려면 가장 멀리 있는 집을 선택해야 한다. 이때 가장 멀리 있는 집의 상자 개수가 0이면 방문할 필요가 없기에 0이 아닌 집이 될 때까지 pop()을 한다.
그다음엔 0이 아닌 가장 멀리 있는 집부터 deliveryCnt 가 0 보다 크면서 deliveries 가 빈 배열이 아닌 동안 박스를 배달한다(while). 방문할 집에 배달할 택배 상자가 0이 아니면 deliveries 값과 deliveryCnt 을 갱신한다. 방문할 집에 배달할 택배 상자가 0이면 pop()을 한다. 수거도 배달과 같기에 pickups 도 똑같이 계산해 주면 된다.

deliveryCnt, pickupCnt 모두 0 이거나 deliveries , pickups 이 빈 배열일 때 배달과 수거하는 집들 중 가장 멀리 있는 집의 인덱스를 알려주는 deliveriesTop, pickupsTop 중 더 큰 값을 선택해 *2 해서 answer에 더한다. (가장 먼 집까지 배달한 후 다시 돌아와야 하기에 곱하기 2)

solution.js
function solution(cap, n, deliveries, pickups) {
    let answer = 0;

    while(deliveries.length || pickups.length) {
        let deliveryCnt = cap;
        let pickupCnt = cap;
        // deliveries
        while(deliveries.length > 0 && deliveries[deliveries.length-1] === 0) {
            deliveries.pop();
        }
        
        const deliveriesTop = deliveries.length;
        while(deliveryCnt > 0 && deliveries.length > 0) {
            if(deliveries[deliveries.length-1] != 0) {
                const top = deliveries[deliveries.length-1];
                deliveries[deliveries.length-1] = (top - deliveryCnt >= 0) ? top - deliveryCnt : 0;
                deliveryCnt = (deliveryCnt - top >= 0) ? deliveryCnt-top : 0;
            }
            if(deliveries && deliveries[deliveries.length-1] === 0) {
                deliveries.pop();
            }
        }
        //pickups
        while(pickups.length > 0 && pickups[pickups.length-1] === 0) {
            pickups.pop()
        }
        
        const pickupsTop = pickups.length;
        while(pickups.length > 0 && pickupCnt > 0) {
            if(pickups[pickups.length-1] != 0) {
                const top = pickups[pickups.length-1];
                pickups[pickups.length-1] = (top - pickupCnt >= 0) ? top - pickupCnt : 0;
                pickupCnt = (top - pickupCnt >= 0) ? 0 : pickupCnt-top;
            }
            if(pickups && pickups[pickups.length-1] === 0) {
                pickups.pop();
            }
        }
        answer += (deliveriesTop > pickupsTop) ? deliveriesTop*2 : pickupsTop*2;
    }
    return answer;
}

댓글