[알고리즘] 문제 풀이

[스택 / 큐] 프로그래머스 - 기능개발

yeon_zoo 2021. 10. 24. 02:30

문제 출처 : 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되는 구조이다. 이렇게 되면 아무래도 매일을 세는 것보다 훨씬 간단하게 구현이 가능하다. 단순한 문제에서도 참 배울 점이 많은 것을 느끼는 것 같다.