KUKJIN LEE
posted 5 months ago
[프로그래머스] 과제 진행하기 Lv.2 JavaScript
-
과제는 정해진 시각에 시작합니다.
-
새로운 과제가 시작되어야 하는 시각에 이전 과제가 아직 진행 중이라면, 이전 과제는 일시 중단하고 새로운 과제를 시작합니다.
-
이전에 진행하던 과제를 완료했을 때, 일시 중단한 과제가 있다면 그 과제를 재개합니다.
-
만약 과제를 끝낸 시각에 새로운 과제와 일시 중단한 과제가 모두 있다면, 새로운 과제를 우선적으로 시작합니다.
-
여러 개의 일시 중단한 과제가 있다면, 가장 최근에 중단한 과제를 우선적으로 재개합니다.
과제의 계획을 담은 이차원 문자열 배열 'plans'이 주어질 때, 과제를 완료한 순서대로 과제의 이름을 배열에 담아 반환하는 'solution' 함수를 작성하는 것이 문제입니다.
function solution(plans) {
var answer = [];
let stack = [];
plans.sort((a,b)=>parseInt(a[1].replace(":",'')) > parseInt(b[1].replace(":",'')) ? 1 : -1)
for(var i= 0; i<plans.length; i++){
if(i == plans.length-1){
answer.push(plans[i][0])
} else {
let a = plans[i];
let b = plans[i+1];
let timeDifMs = new Date(`2023-04-11 ${b[1]}:00`).getTime() - new Date(`2023-04-11 ${a[1]}:00`).getTime()
let dif = timeDifMs/ (1000*60);
if(dif >= a[2]){
answer.push(a[0])
let remainTime = dif - a[2];
while(stack.length > 0 && remainTime > 0){
let popped = stack.pop();
if(popped[1] > remainTime){
stack.push([popped[0], popped[1] - remainTime]);
remainTime =0;
} else {
answer.push(popped[0])
remainTime -= popped[1]
}
}
} else {
stack.push([a[0], a[2]-dif])
}
}
}
while(stack.length !==0){
let p = stack.pop();
answer.push(p[0])
}
return (answer)
}
해설
새로운 일정이 시작되어야 할 때, 현재 일정을 일시 중단하고 새로운 일정을 시작한다는 것입니다. 그리고 가능한 한 빨리 중단한 일정을 재개합니다.
answer 배열과 stack 배열
answer 배열은 완료된 과제의 순서를 담기 위한 것입니다. stack 배열은 일시 중단한 과제를 저장하기 위한 것입니다.
시간은 문자열이므로, :을 제거하고 정수로 변환
plans 배열을 시작 시간 오름차순으로 정렬합니다. 여기서 시간은 문자열이므로, :을 제거하고 정수로 변환하여 비교합니다.
일정 처리
-
마지막 일정이라면, 이를 answer에 즉시 추가합니다.
-
현재 일정(a)과 다음 일정(b) 사이의 시간 차이를 계산합니다. 이 시간 차이는 밀리세컨드로 반환되므로, 분으로 변환하기 위해 60000으로 나눕니다.
-
만약 시간 차이가 현재 일정의 수행 시간보다 크거나 같다면, 현재 일정을 answer에 추가하고, 남은 시간 동안 stack에서 일정을 처리합니다. 이 때, stack에서 꺼낸 일정의 수행 시간이 남은 시간보다 길다면, 일정을 다시 스택에 넣고 남은 시간을 0으로 설정합니다. 그렇지 않다면, 꺼낸 일정을 answer에 추가하고, 남은 시간을 깎습니다.
-
시간 차이가 현재 일정의 수행 시간보다 작다면, 현재 일정을 stack에 넣습니다. 이 때, stack에 넣는 일정의 수행 시간은 남은 시간만큼 줄입니다.
남은 일정 처리
-
모든 일정을 처리한 후에, stack에 남은 일정이 있다면 이를 answer에 추가합니다.
-
완료된 일정 순서를 담은 answer를 반환합니다.