프로그래머스 택배 배달과 수거하기 JavaScript
문제 풀이
상당히 오래 걸린 문제였다.
물류창고에서 n개의 집에 택배를 배달하고 빈 택배 상자를 수거할 때 최소 거리로 이동하는 문제이며,
매개변수로 (cap: 실을 수 있는 최대 택배 상자 개수, n: 집의 개수, deliveries: 집에 배달할 택배 상자 개수 리스트, pickups: 집에서 수가할 택배 상자 개수 리스트)가 주어진다.
스택을 이용해 deliveries 와 pickups 모두 빈 배열이 될 때까지 while을 돌린다.
deliveries 와 pickups 를 따로 계산할 거기에 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)
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;
}