본문으로 바로가기

[Programmers] 기능개발

category Algorithm/Programmers 2023. 5. 16. 00:21
728x90
반응형
프로그래머스 팀에서는 기능 개선 작업을 수행 중입니다. 각 기능은 진도가 100% 일 때 서비스에 반영할 수 있습니다.

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

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


개요

문제가 Stack/Queue라는 카테고리로 분류되어 있어서 그런지 최대한 Stack과 Queue라는 개념을 활용해서 풀어보려고 했으나 정작 이용한 개념은 Stack 밖에 없었다. 초반 로직을 잡아두고 제출했는데 1,2,4,5번의 TestCase에서 실패가 떴다. 

"질문하기"에서 힌트를 얻어 풀 수 있었으며 문제의 자세한 설명은 프로그래머스에 가서 확인하도록 하자.

여기서는 어떤 식으로 풀었는지만 남기려고 한다.


풀이 과정

문제에서는 작업진도(progresses)와 작업 속도(speeds)라는 배열이 주어진다. 문제 설명을 읽어보면 이 작업 진도와 작업 속도를 통해 알아낼 수 있는 건 "작업이 완료되기까지의 남은 날"이다. 프로그래머스의 문제 설명에도 나와있지만 적어보자면 다음과 같다.

progress = [93, 30, 55]	
speeds = [1, 30, 5]

"작업이 완료되기까지의 남은 날"은 다음과 같다.

remain_day = [7 ,2 ,9]

사실 이 "작업이 완료되기까지의 남은 날"을 잘 취합해서 return 하는 게 문제 풀이의 핵심이라고 생각했다. 이 배열을 문제에서 요구하는 형태로 리턴하기 위해 Stack을 통해 다음과 같은 순서를 생각했다.

1. stack의 초기값을 7로 설정하고 이를 start_day라 생각하자.
2. 이후 들어오는 value와 stack의 초기값을 비교하여 value가 더 작다면 stack에 삽입하자.
3. 만약 들어오는 value가 start_day라 지정했던 값보다 크다면 stack에 존재하는 값의 길이를 answer에 append 하고 stack을 비운뒤 새 value를 stack의 초기값으로 지정하고 start_day를 갱신하자.

이 순서대로 로직을 구성하고 코드를 작성했다.


첫 번째 시도

아래 코드는 제일 처음 작성한 코드이다.

def solution(progresses, speeds):
    days = []
    for p, s in zip(progresses, speeds):

        day, remainder = divmod((100 - p), s)
        if remainder != 0:
            day += 1

        days.append(day)

    answer = []

    init = [days[0]]
    for i, v in enumerate(days[1:], start=0):

        if init[0] > v:
            init.append(v)
        if init[0] < v:
            answer.append(len(init))
            init = [v]

    answer.append(len(init))

    return answer

사실 위 코드는 개요에서 언급했듯이 1,2,4,5에 대한 TestCase를 통과하지 못했다. "질문하기"을 통해서 테스트 케이스를 참고했는데 아래 케이스에 대해서 실패했다는 것을 알 수 있었다.

progresses = [99,99,99]
speeds = [1,1,1]

남은 작업 진행속도(speeds)가 모두 같은 경우에 대해 생각하지 못했다는 것을 알 수 있었다. 



두 번째 시도

어떤 경우에는 테스트 케이스를 알아도 코드를 고치기 어려운 경우가 더러 있는데 이번에는 한 줄만 변경하면 되었다.

def solution(progresses, speeds):
    days = []
    for p, s in zip(progresses, speeds):

        day, remainder = divmod((100 - p), s)
        if remainder != 0:
            day += 1

        days.append(day)

    answer = []

    init = [days[0]]
    for i, v in enumerate(days[1:], start=0):

        if init[0] >= v: # (변경) 남아있는 값이 다 같은 경우
            init.append(v)
        if init[0] < v:
            answer.append(len(init))
            init = [v]

    answer.append(len(init))

    return answer



결과

제출한 결과는 다음과 같다.

사실 날짜를 구하는 과정에서 divmod를 사용하기 떄문에 '0'이 들어오면 ZeroDivisionError가 나기 때문에 완벽하다고는 볼 수 없을 것 같지만 통과는 되었으니 나름 흡족하다.

728x90
반응형