[프로그래머스] 디스크 컨트롤러 / JavaScript
알고리즘/프로그래머스

[프로그래머스] 디스크 컨트롤러 / JavaScript

 

 

 

 

 

디스크 컨트롤러

 

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을 작업의 수로 나눠 준다. 소수점은 버린다.