디스크 컨트롤러
https://programmers.co.kr/learn/courses/30/lessons/42627
코딩테스트 연습 - 디스크 컨트롤러
하드디스크는 한 번에 하나의 작업만 수행할 수 있습니다. 디스크 컨트롤러를 구현하는 방법은 여러 가지가 있습니다. 가장 일반적인 방법은 요청이 들어온 순서대로 처리하는 것입니다. 예를
programmers.co.kr
풀이
function solution(jobs) {
let totalTime = 0;
let currentTime = 0;
let waitingRoom = []; //priority queue
const scheduling = () => {
if (!waitingRoom.length) return false;
const [inputTime, workTime] = waitingRoom.shift();
totalTime += currentTime - inputTime + workTime;
currentTime += workTime;
return true;
};
const insertJob = (job) => {
waitingRoom.push(job);
let i = waitingRoom.length - 1;
waitingRoom.sort((a, b) => a[1] - b[1]);
};
jobs
.sort((a, b) => a[0] - b[0])
.forEach(([inputTime, workTime]) => {
while (currentTime < inputTime) {
if (!scheduling()) {
currentTime = inputTime;
}
}
insertJob([inputTime, workTime]);
});
while (waitingRoom.length > 0) {
scheduling();
}
return parseInt(totalTime / jobs.length);
}
1️⃣ 기본적으로 들어온 순으로 처리
2️⃣ 작업 처리 중 다른 요청 발생시 가장 소요 시간이 짧은 작업부터 처리
currentTime
현재 시간 체크
totalTime
각 프로세스 처리 시간의 총합으로, 프로세스 처리 시간은 ( 현재시간 - 요청시점) + 소요시간
이다.
❗️ jobs
는 들어온 순서로 정렬되어있지 않기 때문에 우선적으로 요청 시점 순으로 정렬해주어야 한다.
jobs.sort((a, b) => a[0] - b[0])
.forEach(([inputTime, workTime]) => {
while (currentTime < inputTime) {
if (!scheduling()) {
currentTime = inputTime;
}
}
insertJob([inputTime, workTime]);
});
현재 시간과 비교하여 요청시간이 빠른 작업들을 모두 스케줄러에 넣는다.
현재 시간보다 요청 시간이 더 나중이라면, 스케줄러에 있는 작업들 중에서 처리할 작업을 선별한 후 다시 현재 시간과 요청 시간을비교한다. 만약 스케줄러가 비어있다면 현재 시간을 해당 작업의 요청 시간으로 변경해준다.
작업을 스케줄러에 넣는 동시에 소요시간이 빠른 순으로 스케줄러를 정렬한다.
const insertJob = (job) => {
waitingRoom.push(job);
let i = waitingRoom.length - 1;
waitingRoom.sort((a, b) => a[1] - b[1]);
};
처리할 작업의 선별은 scheduling
에서 담당한다.
const scheduling = () => {
if (!waitingRoom.length) return false;
const [inputTime, workTime] = waitingRoom.shift();
totalTime += currentTime - inputTime + workTime;
currentTime += workTime;
return true;
};
만약 스케줄러(waitingRoom
)가 비어있다면, false
를 리턴해서 현재 시간을 변경하도록 한다.
waitingRoom
은 소요시간이 낮은 작업 순으로 정렬되어있다. 따라서 가장 첫번째 작업을 꺼내서 처리 시간을 totalTime
에 더해주고, 현재 시간(currentTime
)을 작업이 끝난 직후로 변경해준다.
while (waitingRoom.length > 0) {
scheduling();
}
jobs
를 모두 순회 했어도 waitingRoom
에는 아직 처리를 기다리는 작업들이 남아있을 수 있다.
waitingRoom
이 모두 빌 때까지 스케줄링해준다.
return parseInt(totalTime / jobs.length);
평균 시간을 얻기 위해 totalTime
을 작업의 수로 나눠 준다. 소수점은 버린다.