카테고리 없음

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

코드냠냠꿀꺽 2021. 11. 2. 16:09

문제 설명

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

 

예를들어

- 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 이하입니다.
  • 하드디스크가 작업을 수행하고 있지 않을 때에는 먼저 요청이 들어온 작업부터 처리합니다.

문제 접근

1. 문제 예시를 보고 작업 소요시간이 적은 작업부터 처리해야 평균 시간이 줄어든다는 것을 파악했다.

2. 먼저 들어간 작업이 먼저처리되고 하는것이 아닌 '적은 시간을 가진 작업' 이라는 우선순위가 있으므로 heap을 사용하여 소요시간으로 정렬 하면 좋겠다고 생각했다. 

3. 각 작업의 걸리는 시간 = 현재 작업의 전까지의 진행된 작업들의 총 소요시간 - 현재 작업시간의 start 타임 

 

처음 풀이를 할때 한번에 heap에 모든 job을 다넣고 시작하다보니 문제가 꼬이기 시작했다. 

job의 length가 1일때와 2일때 그이상일 경우를 나누었고, 여러 문제들이 발생하였다. 

 

그래서 결국 다른분의 풀이를 참조하여 풀게 되었다ㅠㅠ

 

그렇게 풀게된 코드

import heapq
def solution(jobs):
    answer, now, i = 0, 0, 0
    start = -1
    length = len(jobs)
    heap = []

    while length > i: # 실행된 작업 개수 파악
        for j in jobs:
            if start < j[0] <= now:
                heapq.heappush(heap, (j[1], j[0]))
        if len(heap) > 0:
            cur = heapq.heappop(heap)
            start = now
            now += cur[0]
            answer += now - cur[1]
            i += 1
        else:
            now += 1
    return answer//length

잘못 생각 했던 점

원래 코드 개선 
처음부터 모든 작업을 heap에 넣고 시작 현재 실행할 수 있는 작업들을 넣어놓고 우선순위로 빼서 쓰자
for문을 줄이기 위해 필요없는 경우를 많이 나눔 job의 개수는 상관 없었다.
전 작업이 완료된 시간 start와 현재 시간인 now로 현재 실행할 수 있는 작업인지만 파악
작업이 없는 중간에 비는 시간에 대한 경우를 대비하지 못함 작업이 실행되지 않는 경우 now라는 변수로 +1을 해준다.

 

 

참고 링크!

https://soohyun6879.tistory.com/136