#
문제 설명
과제를 받은 루는 다음과 같은 순서대로
과제를 하려고 계획을 세우기
조건
과제는 시작하기로 한 시각이 되면 시작
새로운 과제를 시작할 시각이 되었을 때, 기존에 진행 중이던 과제가 있다면
진행 중이던 과제를 멈추고 새로운 과제를 시작
진행중이던 과제를 끝냈을 때, 잠시 멈춘 과제가 있다면,
멈춰둔 과제를 이어서 진행
멈춰둔 과제가 여러 개일 경우, 가장 최근에 멈춘 과제부터 시작
매개 변수
plans
반환값
3 ≤ plans의 길이 ≤ 1,000
진행중이던 과제가 끝나는 시각과
새로운 과제를 시작해야하는 시각이 같은 경우
진행중이던 과제는 끝난 것으로 판단
plans | result |
---|---|
[["korean", "11:40", "30"], ["english", "12:10", "20"], ["math", "12:30", "40"]] | ["korean", "english", "math"] |
[["science", "12:40", "50"], ["music", "12:20", "40"], ["history", "14:00", "30"], ["computer", "12:30", "100"]] | ["science", "history", "computer", "music"] |
[["aaa", "12:00", "20"], ["bbb", "12:10", "30"], ["ccc", "12:40", "10"]] | ["bbb", "ccc", "aaa"] |
function solution(plans) {
// start 시간으로 정렬
// onePlan : [name, start, playtime]
plans.sort(([_na, startA, _pa], [_nb, startB, _pb]) => {
const _startA = +startA.replace(":","");
const _startB = +startB.replace(":","");
return _startA - _startB;
})
// 끝내는 시간
const playTime = (start, playTime) => {
const times = start.split(":").map((v) => +v);
const mm = times[1] + +playTime;
if (mm >= 60) {
const hh = ~~(mm / 60);
return `${times[0] + hh}:${mm - hh * 60}`
}
return `${times[0]}:${mm}`
}
// 사이 시간 (단위: 분)
const diffTime = (time1, time2) => {
const times_a = time1.split(":").map((v) => +v);
const times_b = time2.split(":").map((v) => +v);
const hh = times_b[0] - times_a[0];
const mm = times_b[1] - times_a[1];
return hh * 60 + mm;
}
const answer = [];
let stack = [];
let time = plans[0][1];
while (plans.length) {
const [name, start, playTime] = plans.shift();
// 멈춰둔 과제 있을 때
if (stack.length) {
let diff = diffTime(time, start);
while (stack.length && diff > 0) {
if (time == start) break;
const [stoppedName, lastTime] = stack.pop();
diff -= lastTime;
if (diff < 0) {
stack.push([stoppedName, Math.abs(diff)]);
} else {
answer.push(stoppedName);
}
}
}
if (plans.length) {
const [_n, nextStart, _p] = plans[0];
const end = playTime(start, playTime);
if (timeDiff(end, nextStart) < 0) {
const diff = diffTime(start, nextStart);
stack.push([name, playTime - diff]);
} else {
answer.push(name)
}
time = end;
} else {
answer.push(name)
}
}
if (stack.length) {
stack.reverse().forEach(([name, _]) => answer.push(name));
}
return answer;
}
풀이
경우의 수
를 구하여 조건에 맞춰 solution 구하기
- 변수 정의
- playTime : 끝내는 시간을 반환하는 function
- diffTime : 시간과 시간 사이의 차이를 반환하는 function
- stack : 멈춘 과제를 담아두는 대기열
- time : 작업하는 현재 시간
- plans 를 start 시간을 정렬
새로운 과제 있을 때 반복문
time 과 start 시간 사이에 간격이 있을 때
멈춘 과제 있을 때
- diff 시간 차이 반환
시간 간격이 0 이나 멈춘 과제 없어질 때까지 반복문
- start 시간 될때까지 멈춰둔 과제 진행
- diff 와 lastTime 비교후 stack 갱신
멈춘 과제 없을 때 (다음 스케줄 진행)
다음 새로운 과제가 있을 때
- start 에서 playTime 적용한 시간 end 반환
- nextStart 와 비교
- 초과 : stack 에 push
- 완료 : answer 에 push
다음 새로운 과제가 없을 때
- 완료 : answer 에 push
멈춰둔 과제 최신순으로 answer 에 push