프로그래머스 디스크 컨트롤러 코드 및 해설 (파이썬)

2021. 6. 1. 15:31algorithm

반응형

https://programmers.co.kr/learn/courses/30/lessons/42627

 

코딩테스트 연습 - 디스크 컨트롤러

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

programmers.co.kr

 

answer에 각 작업의 요청부터 종료까지 걸린 시간의 합을 저장하고, 마지막에 이를 작업의 개수로 나눠 최종 답을 반환했습니다.

우선 jobs를 요청시점이 이른 순대로, 요청 시점이 같다면 소요시간이 적은 순대로 정렬하여 queue로 변환하고, 현재 시점을 표현하는 now라는 변수를 만들었습니다. now는 첫 작업의 요청시점으로 초기화했습니다.

jobs의 첫 번째 작업부터 차례로 꺼내면서 해당 작업의 요청시점을 request, 소요시간을 elapsedTime으로 저장했습니다. 현재 작업의 요청시점이 이미 지난 경우와 아직 오지 않은 경우로 나누어, 요청시점이 이미 지난 경우는 바로 작업을 시작해 now를 now에서 작업의 소요시간만큼 지난 값으로 수정했고, answer에는 (현재 작업이 끝난 시점인 now) - (현재 작업의 요청 시점) 만큼을 더해주었습니다. 요청시점이 아직 오지 않은 경우는 요청 이후 작업을 시작해야 하기 때문에 now를 (현재 작업의 요청 시점) + (현재 작업의 소요시간)으로 갱신했고, answer에는 소요시간만큼만 더해주었습니다. 기다림 없이 바로 작업이 수행되었기 때문입니다.

이후 현재 작업이 끝난 시점인 now 이전에 요청이 들어온 작업들이 있는지 체크하고, 이들을 소요시간이 적은 순대로 정렬하여 jobs에 다시 삽입했습니다.

이후 jobs에 남은 작업이 없을 때까지 이를 반복합니다.

 

 

from collections import deque 

def solution(jobs):
    # 각 작업의 요청부터 종료까지 걸린 시간의 합 
    answer = 0
    # 작업의 개수 
    N = len(jobs)
    
    # 요청 시점이 이른 순대로, 요청 시점이 같다면 소요 시간이 적은 순대로 정렬
    jobs.sort(key=lambda x: (x[0], x[1]))
    
    # 현재: 첫 작업의 요청 시점 
    now = jobs[0][0]
    
    jobs = deque(jobs)
    
    while jobs:
        request, elapsedTime = jobs.popleft()
        
        # 요청 시점이 이미 지난 경우 
        if now > request:
            # 바로 작업 시작해서 소요시간만큼 시간이 더 흐름 
            now += elapsedTime 
            # 요청 시점이 지나서 작업을 시작했으므로, 요청부터 종료까지 걸린 시간은 (해당 작업이 끝난 현재 시점) - (요청 시점) 
            answer += now - request
        # 아직 요청 시점이 오지 않은 경우 
        else:
            # 요청 시점부터 해당 작업 시작하기 
            now = request + elapsedTime 
            # 요청 하자마자 작업을 했으므로, 요청부터 종료까지 걸린 시간은 작업의 소요시간과 같음 
            answer += elapsedTime
        
        # 해당 작업을 수행하고 있는데 새로운 작업이 요청 들어온 경우 
        waitingList = []
        for job in jobs:
            if job[0] < now:
                waitingList.append(job)
            else:
                break
        
        # 새로 요청 들어온 작업들을 jobs에서 없애고 
        for w in waitingList:
            jobs.remove(w)
            
        # 소요시간 짧은 순대로 정렬 
        waitingList.sort(key=lambda x: x[1])
        
        # 소요시간 짧은 순대로 정렬한 새로 요청 들어온 작업을 jobs와 다시 합침 
        jobs = deque(waitingList) + jobs
                
    
    return int(answer / N)
반응형