본문 바로가기

알고리즘/프로그래머스

[프로그래머스 코딩테스트 고득점 Kit / 스택/큐] 기능개발 (python)

728x90

풀이

from math import ceil

def solution(progresses, speeds):
    answer = []
    left = []
    
    for i in range(len(progresses)):
        left.append(ceil((100 - progresses[i]) / speeds[i]))
    
    first = -1
    cnt = 0
    
    for i in left:
        if first < i: 
            first = i
            if cnt != 0:
                answer.append(cnt)
                cnt = 0
        cnt += 1
    
    answer.append(cnt)
    
    return answer

각 작업의 남은 일수를 left 배열에 담는다. (전체 완료율 100에서 현재 진행률 progresses를 뺀다. 그리고 speed로 나눠서 올림하면 남은 일수가 나온다.)

 

앞의 작업보다 뒤의 작업이 남은 일수가 적으면, 앞의 작업이 완료되는 순간 뒤에 있는 작업도 함께 배포된다. 따라서 앞의 작업보다 뒤의 작업의 남은 일수가 더 클때까지 cnt를 +1한다. 그리고 남은 일수가 더 큰 작업이 나타나면 그 작업을 기준(first)에 할당하고, cnt를 answer 배열에 추가한다. 이때 cnt는 한 번에 처리할 수 있는 작업 수를 의미한다.

 

이를 left의 마지막까지 반복하면 cnt에 마지막으로 처리할 작업의 개수가 남아있다. 이는 for문을 나가서 answer에 마지막으로 한 번 넣어주면 answer 배열을 완성할 수 있다.

 

더보기

이전풀이

풀이 1

import math

def solution(progresses, speeds):

    answer = []
    
    queue = []
    for i in range(len(progresses)):
        queue.append(math.ceil((100 - progresses[i])/speeds[i]))
    
    while(True):
        try:
            cur = queue[0]
            cnt = 0

            for i in range(len(queue)):
                queue[i] = queue[i] - cur

            while(queue[0] <= 0):
                queue.pop(0)
                cnt += 1
            answer.append(cnt)

        except IndexError:
            answer.append(cnt)
            break

    
    return answer

내 풀이

  • 남은 작업 일수 배열 queue를 만들어줌. ceil은 올림 함수.
  • 배열 순서대로 남은 작업일수를 빼주고, 0보다 작은 애들은 pop하고, pop한 횟수(cnt)를 answer에 저장함.

ex)

작업 [93, 30, 55]
속도 [1, 30, 5]
남은 작업 일수 [7, 3, 9]

일 때, 처음 작업을 완료하려면 7일이 필요함

for i in range(len(queue)):
                queue[i] = queue[i] - cur

위 for문을 돌고 나면 남은 작업 일수는 [7, 3, 9] -> [0, -4, 2]가 됨.

그러면 앞에서부터 0보다 작은 작업은 pop해주고, 완료해준 만큼 횟수(2)를 정답 배열에 저장.

 

바깥 while문을 한 번 돌고나면 남은 작업 일수는 [2]가 됨.

마찬가지로 위 for문을 돌면 [0]이 되고

while(queue[0] <= 0):
                queue.pop(0)
                cnt += 1
            answer.append(cnt)

안쪽 while문을 돌면 남은 작업 일수는 [] 빈 배열이 됨. (cnt=1)

그리고 다시 위 while문을 돌려고 하면 IndexError 발생(빈 배열이라서)

        except IndexError:
            answer.append(cnt)
            break

IndexError은 예외처리되고, cnt는 정답 배열에 저장하고 바깥 while문 탈출

 

풀이 2

from math import ceil

def solution(progresses, speeds):
    daysLeft = list(map(lambda x: (ceil((100 - progresses[x]) / speeds[x])), range(len(progresses))))
    count = 1
    answer = []

    for i in range(len(daysLeft)):
        try:
            if daysLeft[i] < daysLeft[i + 1]:
                answer.append(count)
                count = 1
            else:
                daysLeft[i + 1] = daysLeft[i]
                count += 1
        except IndexError:
            answer.append(count)
    
    return answer

모범 답안 참고.

<풀이 1의 문제점>

  • 풀이 1에서는 반복문이 3개나 사용됨
  • 모범 답안을 보니까.. 남은 작업 일수 queue를 만들어놓고 제대로 활용하지 못했다는 생각이 들었다.
  • 남은 작업 일수랑 pop을 동시에 사용할 필요가 없는듯. 남은 작업 일수 라는 배열을 사용할 거면 좀 더 머리를 써서 pop기능을 없애야하고, 배열을 만들지 않을거면 pop 기능을 써서 최대한 간단하게 구현해야함.

배울점이 많다..

분발합시다

 

반응형