본문 바로가기
알고리즘

[Swift 알고리즘] 디스크 컨트롤러

by 마라민초닭발로제 2023. 5. 15.

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

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

 

풀이방법 :

0. 제일 중요

    인풋갑인 Jobs는 정렬된 값이 아니다. 무슨 말 이냐면

    jobs = [[0, 10] , [1, 20] ,[3, 40]] 이렇게 정렬 될 수도 있지만,

    jobs = [[4,10], [1, 2], [0, 20]] 일 수도 있다. 

1. 이것은 readyQueue를 구현하여 계산한다.

    - readyQeuue는 실행 순서대로 정렬한다.

    - 만약 실행순서가 같을 경우, 먼저 들어온 순서대로 정렬한다.

2. time을 천천히 1씩 증가시키는 방법은 시간초과가 난다.

 

코드 구현

func solution(_ jobs:[[Int]]) -> Int {
    var time = 0
    var readyQueue:[[Int]] = []
    var jobsQueue = jobs.sorted { t1, t2 in
        return t1[0] < t2[0]
    }
    var sumTime = 0 //테스크마다 (현재시간 - 시작시간)을 더한 값
    
    while !jobsQueue.isEmpty || !readyQueue.isEmpty { //큐가 돌아가기 위한 조건
        while !jobsQueue.isEmpty && jobsQueue[0][0] <= time { //만약 현재 time에 readyQueue로 옮겨지지 않은 대기중인 task들을 readyQueue로 쌓는다.
            let node = jobsQueue.removeFirst()
            readyQueue.append(node)
        }
        readyQueue = readyQueue.sorted{ t0, t1 in
            if t0[1] == t1[1] {
                return t0[0] < t1[0]
            }
            return t0[1] < t1[1]
        } // 큐를 정렬한다.
        if readyQueue.isEmpty { //레디큐가 비어있을 때 jobsQueue[0]가 들어오는 time으로 세팅
            time = jobsQueue[0][0]
        }

        if !readyQueue.isEmpty{ // readyQueue가 비어있지 않을 때 테스크 실행
            let node = readyQueue.removeFirst()
            time += node[1]
            sumTime += time - node[0]
        }//주의할 점은 레디큐가 실행하면서 테스크들을 받을 경우가 있기에 while문 윗부분 부터 다시 실행해야 한다.
    }
    return sumTime / jobs.count
}