[Python] 프로그래머스 - 디스크 컨트롤러 (힙)

yunyoung·2021년 1월 18일
7

알고리즘

목록 보기
10/41

문제 설명

📃 문제 링크

하드디스크는 한 번에 하나의 작업만 수행할 수 있습니다. 디스크 컨트롤러를 구현하는 방법은 여러 가지가 있습니다. 가장 일반적인 방법은 요청이 들어온 순서대로 처리하는 것입니다.

예를들어

- 0ms 시점에 3ms가 소요되는 A작업 요청
- 1ms 시점에 9ms가 소요되는 B작업 요청
- 2ms 시점에 6ms가 소요되는 C작업 요청

와 같은 요청이 들어왔습니다. 이를 그림으로 표현하면 아래와 같습니다.

한 번에 하나의 요청만을 수행할 수 있기 때문에 각각의 작업을 요청받은 순서대로 처리하면 다음과 같이 처리 됩니다.

- A: 3ms 시점에 작업 완료 (요청에서 종료까지 : 3ms)
- B: 1ms부터 대기하다가, 3ms 시점에 작업을 시작해서 12ms 시점에 작업 완료(요청에서 종료까지 : 11ms)
- C: 2ms부터 대기하다가, 12ms 시점에 작업을 시작해서 18ms 시점에 작업 완료(요청에서 종료까지 : 16ms)

이 때 각 작업의 요청부터 종료까지 걸린 시간의 평균은 10ms(= (3 + 11 + 16) / 3)가 됩니다.

하지만 A → C → B 순서대로 처리하면

- A: 3ms 시점에 작업 완료(요청에서 종료까지 : 3ms)
- C: 2ms부터 대기하다가, 3ms 시점에 작업을 시작해서 9ms 시점에 작업 완료(요청에서 종료까지 : 7ms)
- B: 1ms부터 대기하다가, 9ms 시점에 작업을 시작해서 18ms 시점에 작업 완료(요청에서 종료까지 : 17ms)

이렇게 A → C → B의 순서로 처리하면 각 작업의 요청부터 종료까지 걸린 시간의 평균은 9ms(= (3 + 7 + 17) / 3)가 됩니다.

각 작업에 대해 [작업이 요청되는 시점, 작업의 소요시간]을 담은 2차원 배열 jobs가 매개변수로 주어질 때, 작업의 요청부터 종료까지 걸린 시간의 평균을 가장 줄이는 방법으로 처리하면 평균이 얼마가 되는지 return 하도록 solution 함수를 작성해주세요. (단, 소수점 이하의 수는 버립니다)

제한 사항

  • jobs의 길이는 1 이상 500 이하입니다.
  • jobs의 각 행은 하나의 작업에 대한 [작업이 요청되는 시점, 작업의 소요시간] 입니다.
  • 각 작업에 대해 작업이 요청되는 시간은 0 이상 1,000 이하입니다.
  • 각 작업에 대해 작업의 소요시간은 1 이상 1,000 이하입니다.
  • 하드디스크가 작업을 수행하고 있지 않을 때에는 먼저 요청이 들어온 작업부터 처리합니다.

입출력 예

jobsreturn
[[0, 3], [1, 9], [2, 6]]9

문제 풀이

현재 시점에서 처리할 수 있는 작업들을 힙에 넣고, 하나를 뽑아 현재 시점과 총 대기시간을 구해주는 것을 모든 작업을 처리할 때까지 반복한다.

힙에 push를 할 때는 작업의 소요 시간 기준으로 최소힙이 만들어져야 하기 때문에 jobs의 요소를 그대로 넣지 않고 [작업의 소요 시간, 작업이 요청되는 시점]으로 요소의 앞 뒤를 바꿔서 넣어준다.

현재 시점에서 처리할 수 있는 작업인지를 판별하는 조건은 작업의 요청 시간바로 이전에 완료한 작업의 시작 시간(start)보다 크고 현재 시점(now)보다 작거나 같아야 한다.

만약 현재 처리할 수 있는 작업이 없다면, 남아 있는 작업들의 요청 시간이 아직 오지 않은 것이기 때문에 현재 시점(now)을 하나 올려준다.

소스 코드

profile
🌈TIL과 개발 노트

6개의 댓글

comment-user-thumbnail
2021년 4월 10일

로직 진짜 예술이네요..잘 읽었습니다!

답글 달기
comment-user-thumbnail
2021년 6월 4일

와 잘 봤습니다. 혹시 코드 작성 부분은 어떤 툴을 이용하신 건가요!?

답글 달기
comment-user-thumbnail
2021년 8월 27일

게시물 잘 읽었습니다 :)

jobs를 sort 해준 뒤에
for j in jobs -> for j in jobs[i:]
로 변경한다면 더 효율성있는 알고리즘이 될 것 같습니다 !

답글 달기
comment-user-thumbnail
2021년 10월 14일

도움 많이 됐습니다 감사합니다 !

답글 달기
comment-user-thumbnail
2023년 2월 6일

개인적으로 왜 항상 지금 순간에 처리 가능한 job중에 가장 적게 걸리는 job을 선택해야만 전체 요청-처리 평균 시간이 줄어드는가에 대해 직관적으로 이해가 안되서 생각을 해봤는데, 다음과 같이 증명이 되는 것 같습니다.
직관적으로 이해가 되시는 분은 무시하시고 지나가시면 될듯합니다.

지금 순간에 job1, job2가 처리 가능하다고 하면,
job 1: a, l (a: 기다린 시간, l: 걸리는 시간)
job 2: b, m (b: 기다린 시간, m: 걸리는 시간)
(가정: l>m)

만약 1번-2번 순서대로 한다면,
total = (a + l) + (b + l + m) = a + b + 2l + m

만약 2번-1번 순서대로 한다면,
total = (b + m) + (a + m + l) = a+ b + 2m + l

가정에서 l > m 이므로
2번-1번이 항상 더 작은 total을 가짐 -> 더 작은 평균 시간
이렇게 결론이 나는것 같습니다.

1개의 답글