[Algorithm] 프로그래머스 : 기능개발

1Consumption·2020년 3월 9일
2

Algorithm

목록 보기
7/8

프로그래머스 lv2 : 기능개발

코드

import Foundation

func solution(_ progresses:[Int], _ speeds:[Int]) -> [Int] {
    let progressQueue = Queue()
    var orderOfRelease = [Int]()
    
    for index in 0..<progresses.count {
        progressQueue.enqueue(element: (percentage: progresses[index], speed: speeds[index]))
    }
    
    while progressQueue.isEmpty() != true {
        var releaseCount = 0
        progressQueue.progressing()
        
        var progress = progressQueue.dequeue()
        
        while progress.percentage >= 100 {
            releaseCount += 1
            if progressQueue.isEmpty() != true {
                progress = progressQueue.dequeue()
            } else {
                break
            }
        }
        
        if progress.percentage < 100 {
            progressQueue.enqueueFirst(element: progress)
        }
        
        if releaseCount != 0 {
            orderOfRelease.append(releaseCount)
        }
    }
    
    return orderOfRelease
}

class Queue {
    var list = [(percentage: Int, speed: Int)]()
    
    func dequeue() -> (percentage: Int, speed: Int) {
        return list.removeFirst()
    }
    
    func enqueue(element: (percentage: Int, speed: Int)) {
        list.append(element)
    }
    
    func enqueueFirst(element: (percentage: Int, speed: Int)) {
        list = [element] + list
    }
    
    func isEmpty() -> Bool {
        return list.isEmpty
    }
    
    func count() -> Int {
        return list.count
    }
    
    func progressing() {
        for index in 0..<list.count {
            list[index].percentage += list[index].speed
        }
    }
}

풀이과정

매개변수로는 먼저 배포되어야 하는 순서대로 작업의 진도가 적힌 정수 배열 progresses, 각 작업의 개발 속도가 적힌 정수 배열 speeds가 주어진다.

이를 위해 (percentage: Int, speed: Int) 튜플을 배열로 가지는 Queue인 progressQueue를 선언한다. 그리고 progresses 와 speeds의 각 요소를 튜플로 묶어 progressQueue에 enqueue 해준다. 주요 로직은 다음과 같다.

  1. queue내의 모든 list의 percentage에 각 speed를 더한다.
  2. dequeue한 값을 progress에 넣어주고 progress의 percentage가 100 이상이라면(작업이 완료 됐다면) releaseCount를 1 증가시켜준다.
  3. queue가 비어있지 않다면 dequeue를 한번 더 하고 해당 값을 다시 progress에 할당해준다.
  4. queue가 비어있다면 해당 작업을 멈춘다.
  5. 2 ~ 4 작업을 progress의 percentage가 100 미만(작업이 완료되지 않은 경우)일 때까지 반복한다
  6. progress의 percentage가 100 미만(작업이 완료되지 않은 경우)이라면 다시 progressQueue 대기열 맨 앞에 넣어준다.
  7. releaseCount가 0이 아니라면 orderRelease 배열에 append 해준다.

아쉬운 점

나는 대강 로직을 짜고 바로 코드로 옮기는 경향이 있는데 이 경우 오류가 발생하게 되면, 그 오류가 아무리 사소한 오류일지라도 찾는데 시간이 조금 걸린다. 따라서 앞으로는 로직을 완벽하게 짜고, 이를 문서화시켜 검토한 후 문제가 없다고 판단되면 코드로 옮겨야겠다.

아 그리고 저번 포스팅 때 Queue 클래스를 계속 선언하여 아쉽다는 말을 남겼었는데, 이번에도 쓴 이유는 Queue 클래스를 사용 안하고 배열로 바로 하려니 가독성도 안좋아지고, 어차피 똑같은 양의 코드가 나온다는 점이다.

profile
개발자가되고싶어요

2개의 댓글

comment-user-thumbnail
2020년 3월 9일

레벨이 높으시네요!

답글 달기
comment-user-thumbnail
2020년 3월 9일

👍

답글 달기