티스토리 뷰

PS

[Swift]프로그래머스_기능개발

희철 2022. 4. 18. 04:05

문제 설명

 

프로그래머스 팀에서는 기능 개선 작업을 수행 중입니다. 각 기능은 진도가 100%일 때 서비스에 반영할 수 있습니다.

또, 각 기능의 개발속도는 모두 다르기 때문에 뒤에 있는 기능이 앞에 있는 기능보다 먼저 개발될 수 있고, 이때 뒤에 있는 기능은 앞에 있는 기능이 배포될 때 함께 배포됩니다.

먼저 배포되어야 하는 순서대로 작업의 진도가 적힌 정수 배열 progresses와 각 작업의 개발 속도가 적힌 정수 배열 speeds가 주어질 때 각 배포마다 몇 개의 기능이 배포되는지를 return 하도록 solution 함수를 완성하세요.

  • 작업의 개수(progresses, speeds배열의 길이)는 100개 이하입니다.
  • 작업 진도는 100 미만의 자연수입니다.
  • 작업 속도는 100 이하의 자연수입니다.
  • 배포는 하루에 한 번만 할 수 있으며, 하루의 끝에 이루어진다고 가정합니다. 예를 들어 진도율이 95%인 작업의 개발 속도가 하루에 4%라면 배포는 2일 뒤에 이루어집니다.

예시

             progresses                    speeds        return

[93, 30, 55] [1, 30, 5] [2, 1]
[95, 90, 99, 99, 80, 99] [1, 1, 1, 1, 1, 1] [1, 3, 2]

첫 번째 예를 보면 현재 진행중인 작업이 3개 있으며 각각 93%, 30%, 55% 진행된 상태이다. 또한 각각 하루에 1%, 30%, 5%씩 진행할 수 있으므로 다음 날엔 [94, 60, 60]이 될 것이다. 뒤의 작업이 100%가 되어도 앞의 작업이 100%가 되지 않으면 배포할 수 없다. 따라서 첫 작업이 100%가 됐을 때 두 번째 작업도 이미 100%를 완료한 상태이다. 하지만 마지막 작업은 아직 완료되지 않았으므로 2개 배포하고, 나중에 1개를 배포하므로 [2,1]이다.

 

풀이

 

progresses를 배열로 받지만 맨 완료된 작업을 맨 앞에서 차례대로 빼준다면 pop보다 시간복잡도가 클 것이므로 pop을 이용하기 위해 reverse를 이용하였다. 물론 reverse 자체도 시간복잡도가 O(n)이지만 내 풀이는 완료된 작업을 반복해서 빼줄 것이므로 빼는 작업의 시간복잡도가 작으면 좋다고 생각했다.

먼저, 하나의 작업만 있을 경우엔 바로 [1]을 리턴하도록 해주었다. 아닐 경우엔 while문 안에서 zip을 이용해 progresses에 speeds를 한 번씩 더하도록 해주었다. 매번 마지막 값(원래는 가장 첫 작업)이 100이상일 경우에만 100보다 작은 값이 올 때까지 popLast를 해준다. 빼줄때마다 count에 1을 더해주어 동시에 몇 개를 배포하는지 구해주었다.

배열의 last메서드를 이용하면 가장 마지막 값을 옵셔널로 리턴받는다. 이때, 배열의 원소가 2개까지는 pop을 해주어도 last가 nil이 아니기때문에 원소가 1개일 경우를 제외하고는 last!를 통해 구현해주었다. 

while문은 배열 안에 작업이 하나 남았을 경우에만 탈출하기 때문에 탈출한 뒤 남은 값이 100이 넘는다면 마지막 배포 count에 1을 더해주도록 하였고, 아닐 경우엔 result에 따로 1을 append해주었다.

 

import Foundation

func solution(_ progresses:[Int], _ speeds:[Int]) -> [Int] {

    var revProgress: [Int] = progresses.reversed()
    let revSpeed: [Int] = speeds.reversed()
    var result: [Int] = []
    var count = 0
    
    if revProgress.count == 1{
        result = [1]
    } else {
        while revProgress.count != 1 {
            revProgress = zip(revProgress, revSpeed).map {$0 + $1}
            if revProgress.last! >= 100 {
                while revProgress.last! >= 100 {
                    revProgress.popLast()
                    count += 1
                    if revProgress.count == 1{
                        break
                    }
                }
                result.append(count)
                count = 0
            }
        }
        if revProgress[0] >= 100 {
            if var last = result.last {
                last += 1
                result.popLast()
                result.append(last)
            }
        } else {
            result.append(1)
        }
    }
    return result
}

 

결론

 

이번 문제는 스택/큐 분류의 문제이다. 스택과 큐가 어떤 개념인지는 알고있지만 이를 이용해서 잘 푼건지는 솔직히 모르겠다. 그래도 고민하면서 다른 분들의 코드를 참고하지않고 풀어서 뿌듯하다. 

'PS' 카테고리의 다른 글

[Swift]프로그래머스_오픈채팅방  (0) 2022.04.21
[Swift]프로그래머스_프린터  (0) 2022.04.19
[Swift]프로그래머스_H-Index  (0) 2022.04.17
[Swift]프로그래머스_가장 큰 수  (0) 2022.04.17
[Swift]프로그래머스_카펫  (0) 2022.04.17
댓글
최근에 올라온 글
Total
Today
Yesterday