[스택 / 큐] 프로그래머스 - 기능개발
문제 출처 : https://programmers.co.kr/learn/courses/30/lessons/42586
문제 설명 :
기능 개선 작업을 수행 중이다. 문제에서는 각 기능의 개발 속도와 개발 작업의 진도가 적힌 배열이 주어진다. 작업 진도 배열에서 뒤에 있는 원소는 앞에 있는 원소보다 우선 배포할 수 없다. 만약 0번째에 있는 작업이 100% 완성되었을 때, 1번째에 있는 작업은 이미 완성된 후라면 첫 번째 배포 날에 1번 작업까지 배포할 수 있다. 각 배포마다 몇 개의 기능을 배포할 수 있는지를 return 하는 함수를 만들어 보자.
입출력 예시
progresses | speeds | return |
[93, 30, 55] | [1, 30, 5] | [2, 1] |
[95, 90, 99, 99, 80, 99] | [1, 1, 1, 1, 1] | [1, 3, 2] |
문제 풀이 :
def solution(progresses, speeds):
n = len(progresses)
answer = []
while len(progresses) > 0:
for i in range(n):
progresses[i] += speeds[i]
if progresses[0] >= 100:
count_done = 0
while progresses[0] >= 100:
n -= 1
count_done += 1
del progresses[0]
del speeds[0]
if len(progresses) == 0:
break
answer.append(count_done)
return answer
먼저 progresses에 날마다 진척되는 진도를 업데이트 해주면서 100이 넘는 수는 pop해주는 구조를 생각했다. 따라서 남은 progresses에 하루 진도량을 더하고, 그 더해진 배열에서 0번째 값(progresses[0])이 100을 넘었다면 pop해준다. 이 때 첫 원소가 100 미만인 값이 나올 때까지 pop해주고 pop한 횟수를 더해서 그 날 몇 개의 기능을 한꺼번에 배포했는지 표시해준다. 이 과정을 마지막 원소가 pop되고 progresses에 아무것도 남지 않을 때까지 반복해주면 된다.
개선 사항 :
문제를 풀면서도 뭔가 깔끔하게 작성한 코드라는 느낌은 없었다. 가장 생각하기 쉽고 구현하기 쉬운 방법이었던 것 같다. 같은 방법이라도 조금 더 깔끔하게 작성된 코드들도 있었다. 그리고 프로그래머스에 공개된 코드 중에 인상적인 코드가 있었다.
from math import ceil
def solution(progresses, speeds):
daysLeft = list(map(lambda x: (ceil((100 - progresses[x]) / speeds[x])), range(len(progresses))))
count = 1
retList = []
for i in range(len(daysLeft)):
try:
if daysLeft[i] < daysLeft[i + 1]:
retList.append(count)
count = 1
else:
daysLeft[i + 1] = daysLeft[i]
count += 1
except IndexError:
retList.append(count)
return retList
코드 전체에 try, except를 사용한 점이 가장 신기했다. 사용해볼까 싶기는 했지만, 예외 처리된 케이스에 내가 예외 처리하고 싶지 않은 케이스가 되려 포함될 것 같아서 사용하지 못했다. 나처럼 매일 얼마씩 증가했는지를 표시하지 않고, 각 작업이 완성되기까지 걸리는 날을 계산해서 소요되는 날짜가 앞 선 index의 날짜보다 적으면 다 pop되는 구조이다. 이렇게 되면 아무래도 매일을 세는 것보다 훨씬 간단하게 구현이 가능하다. 단순한 문제에서도 참 배울 점이 많은 것을 느끼는 것 같다.