파이썬 문제 풀기

[파이썬] 프로그래머스 코테 연습 > 스택/큐 > 기능개발 풀이

왓썹니야 2022. 3. 2. 17:53

 

LEVEL 2 / 사용언어 : Python3

문제 : https://programmers.co.kr/learn/courses/30/lessons/42586

 

코딩테스트 연습 - 기능개발

프로그래머스 팀에서는 기능 개선 작업을 수행 중입니다. 각 기능은 진도가 100%일 때 서비스에 반영할 수 있습니다. 또, 각 기능의 개발속도는 모두 다르기 때문에 뒤에 있는 기능이 앞에 있는

programmers.co.kr

 

 

  • 문제 설명

프로그래머스 팀에서는 기능 개선 작업을 수행 중입니다. 각 기능은 진도가 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]
  • 코드
def solution(progresses, speeds):
	
    #모듈 import
    from collections import deque
    import math

    days = []
    answer = [1]

	#입력값 deque로 변환
    pr = deque(progresses)
    sp = deque(speeds)

	#작업 완료 날짜 리스트 days 만들기
    for i in range(len(pr)):  
        A = pr.popleft()
        B = sp.popleft()
        day =  math.ceil ((100 - A) / B)
        days.append(day)

	#answer 구하기
    for i in range(1,len(days)) :
        if days[i-1] >= days[i] :
            answer[-1] += 1
            days[i] = days[i-1]
        else :
            answer.append(1)
            
    return answer

 

  • 결과
정확성 테스트
테스트 1 통과 (0.01ms, 10.3MB)
테스트 2 통과 (0.11ms, 10.2MB)
테스트 3 통과 (0.07ms, 10.2MB)
테스트 4 통과 (0.02ms, 10.3MB)
테스트 5 통과 (0.01ms, 10.2MB)
테스트 6 통과 (0.02ms, 10.4MB)
테스트 7 통과 (0.04ms, 10.1MB)
테스트 8 통과 (0.02ms, 10.2MB)
테스트 9 통과 (0.03ms, 10.2MB)
테스트 10 통과 (0.04ms, 10.1MB)
테스트 11 통과 (0.01ms, 10.2MB)

 


  • 풀이가 궁금하다면 클릭
더보기

프로그래머스에서 문제를 풀 때 시간 초과가 나왔던 경험이 많아서... 리스트의 값을 빼야하는 상황이 오면 collections.deque 모듈을 사용하는 편이다. 파이썬은 리스트보다 deque 모듈을 사용하는 것이 더 빠르다고 한다.

(이유는 모름. 언젠간 공부하면 링크를 걸겠음.)

 

 

 

1. 각 작업이 배포될 날짜 리스트 만들기 (days)

 

     A = 작업 진도 ( deque.popleft() : 가장 왼쪽 값을 빼내기 )

     B = 작업 속도

     A + ( B * day ) = 100

    이 방정식을 풀면 

     day = ( 100 - A ) / B

     소숫점이 나오면 무조건 다음 숫자이기 때문에 math 모듈의 ceil 메서드를 이용해서 결과값을 올림해줬다.

이렇게 나온 day 들을 작업 차례대로 days 에 넣으면 작업이 완료되는 날짜들을 저장해놓은 days 리스트 완성.

 

 

2. days 의 원소들을 비교

 

  • 다음 작업이 완성되는 날이 앞선 작업이 완성되는 날보다 작거나 같을 때 :

      앞선 작업이 배포되는 날 같이 배포 = answer 의 마지막 index 의 숫자 + 1, days 의 리스트 값 변경 필요

 

  • 아닌 경우 :

      다른 날 배포 = answer에 1 을 추가

 

가장 처음 완성된 작업이 무조건 있기 때문에 answer에 [1] 을 먼저 넣었다.

 

days 의 1번째 원소부터 검사한다. 1번째 작업이 완성되는 day 가 0번째 작업이 완성되는 day 보다 작다는 것은 (또는 같다는 것은),

이미 작업은 끝났으니 0번째 작업이 배포되는 날 함께 배포하겠다는 뜻이다.

그러니 answer의 0번째 원소 ( 0번째 작업 배포되는 날 배포된 기능 개수) 에 1 을 더해주어야 한다. 

 

그리고 원소를 함께 배포하는 day 로 바꿔주어야 한다. 다음 원소들을 검사할 때 오류가 나지 않으려면. 

 

 

반대로 1번째 작업이 완성되는 day 가 0번째 작업이 완성되는 day 보다 크다는 것은,,

다른 날 그 작업을 배포해야 한다는 뜻이다. 그러니 answer 에 1을 추가해주어야 한다.

( 배포되는 날이 추가됐으니까. )

 

이걸 작업이 있는 개수만큼 반복한다. 

 

난 이렇게 풀었다. 다른 사람 풀이를 보니 알고리즘은 비슷한 듯 하다.