[파이썬] 프로그래머스 코테 연습 > 스택/큐 > 기능개발 풀이
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을 추가해주어야 한다.
( 배포되는 날이 추가됐으니까. )
이걸 작업이 있는 개수만큼 반복한다.
난 이렇게 풀었다. 다른 사람 풀이를 보니 알고리즘은 비슷한 듯 하다.