밍맹의 생각날 때 적는 블로그

[프로그래머스/Python] 기능개발 (Level - 2) 본문

알고리즘(Python)

[프로그래머스/Python] 기능개발 (Level - 2)

mingmaeng 2020. 2. 12. 18:09

문제

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

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

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

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

 


리스트에 있는 기능들은 각각의 개발 속도에 따라 개발이 완료되고, 개발이 100%가 됐을 경우 배포를 한다.

여기서, 배포는 가장 앞 열에 있는 기능이 100%가 됐을 경우 연속되는 기능들이 배포가 된다.

 

하나의 예시를 들면 , [ a (100%) , b (100%), c(95%) , d(100%) ]일 경우 배포되는 기능은 a, b 단 두개 뿐이다.

기능 개발의 흐름은 다음과 같다.

 

  1. 각각의 기능이 개발 속도에 따라 진행된다.
  2. 맨 앞의 기능이 100이 넘었는지 확인한다.
  3. 넘었을 경우 배포하고, 리스트에서 지운다. 그리고 다시 2번으로 돌아간다.
  4. 넘지 않았을 경우 1로 넘어 간다.

이런 흐름을 가진 상태로, 추가적으로 기능 개발이 하나만 남았을 경우 어차피 하나만 배포되기 때문에 1을 반환해준다.

1번 작업을 진행할 때 반복문을 이용하여 모든 요소에 접근해 값을 더해줬으나, 리스트의 길이가 같은 두 개의 리스트 요소를 서로 더할 때 다음과 같이 하면 정말 편하다.

 

from operator import add
...

c = list(map(add, a, b))

 

operator.add()와 map()함수를 이용하면 다음과 같이 두 개의 리스트를 서로 더해 줄 수 있다.

a = [ 1, 2, 3 ] , b = [ 2, 3, 4 ] 라고 할 때 위의 식을 통해 c = [ 3, 5, 9 ] 라는 리스트를 얻을 수 있다.

deque에도 적용시킬 수 도 있어서 1번 기능은 다음 식을 응용하였다.

 

아래는 전체 코드다.

 

from collections import deque
from operator import add

def solution(progresses, speeds):
    answer = []
    
    que_progresses = deque(progresses) # 작업 개수 리스트를 큐로 변환
    que_speeds = deque(speeds) # 작업 속도 리스트를 큐로 변환
    
    while que_progresses :
        count = 0 # 배포마다 기능이 몇 개인지 저장하는 변수
        que_len = len(que_progresses)
        
        # 기능 개발이 한개만 남았을 경우 날짜와 상관없이 무조건
        # 하나만 배포하므로 answer에 1을 추가해주고 종료
        if que_len == 1 :
            answer.append(1)
            break
        
        # 개발 진행도 + 개발 속도 -> 개발 진행도 갱신
        que_progresses = deque(map(add, que_progresses, que_speeds))
        
        # 개발진행이 완료 되었으면 배포
        while que_progresses :
            if que_progresses[0] >= 100 :
                que_progresses.popleft()
                que_speeds.popleft()
                count += 1
            else :
                break
                
                
        if count != 0 :
            answer.append(count)
            
    return answer

 

맨 앞의 기능먼저 배포하기 때문에 시간복잡도를 이용해 deque를 이용했다.

주의할 점은 , while문의 조건식을 단순이 True가 아닌 작업 개수 큐의 요소가 존재하는지로 확인해야 한다.

[100 , 100] 일 경우 두 개의 기능이 한 번에 배포되기 때문에, 항상 큐가 비어있는지 확인해줘야 한다.

Comments