알고리즘/스택,큐

[프로그래머스] 기능개발 - 파이썬(python)

아뵹젼 2022. 5. 7.

 

나의 풀이

from math import ceil

def solution(progresses, speeds):
    releases = []
    step = -1 # releases list 의 index (각 배포 index)
    tmp = 0 # 기준이 되는 앞에 있는 기능의 배포일수
    
    for i,progress in enumerate(progresses):
        if (ceil((100-progress)/speeds[i])<= tmp) :
            releases[step] += 1
        else :
            step += 1
            tmp = ceil((100-progress)/speeds[i])
            releases.append(1)
        
    return releases

내가 생각한 알고리즘은 다음과 같다.

 

먼저 배포되어야 하는 순서대로 작업의 진도가 적힌 정수 배열 progresses 을 반복문으로 돈다.

releases 는 각 배포마다 몇 개의 기능이 배포되는지를 나타내는 list 이다.

ex) [2,1] 은 첫 번째 배포에서 2개의 기능, 두 번째 배포에서 1개의 기능이 배포되었음을 뜻한다.

 

tmp 는 나보다 앞에 있는 우선순위가 높은 작업에 걸리는 배포일을 뜻한다.

 

알고리즘 예시)

progresses 가 [93,30,55] 이고 speed가 [1,30,5] 일 때 각 작업을 반복문으로 돌면서 탐색해보자.

맨 처음에 93 을 탐색한다. 처음엔 tmp 가 0으로 초기화되어있으므로, 

(100-93)/1 = 7 (배포에 걸리는 시간) 이 당연히 x 보다 크므로,

하나의 배포를 추가한다. -> step += 1

그리고 기준이 되는 작업의 배포일 tmp 를 7일로 설정한다.

그리고, release 리스트의 첫 번째 배포에 1개의 기능을 추가한다.

 

다음으로 30 을 탐색한다. (100-30)/30 + 1 = 3일은 tmp 의 7일보다 작으므로,

93 작업이 배포될 때 함께 배포될 수 있다.

따라서 release[0] , 즉 첫 번째 배포에 1개의 기능을 추가해준다. -> releases[step] += 1

 

마지막으로 55를 탐색한다. (100-55)/5 = 9일이다.

7일 보다 더 오래걸리므로, 앞의 두 작업과 함께 배포될 수 없다.

따라서 releases 리스트에 다른 배포를 추가하기 위해 releases.append(1) 을 실행한다.

 

그렇다면 releases 리스트의 결과는 [2,1] 이 된다.

즉, 첫 번째 배포에 (7일, 3일) 의 기능이 포함되며,

두 번째 배포에 (9일)이 걸리는 기능이 포함되는 것이다.

 

 

다른 풀이

def solution(progresses, speeds):
    Q=[]
    for p, s in zip(progresses, speeds):
        if len(Q)==0 or Q[-1][0]<-((p-100)//s):
            Q.append([-((p-100)//s),1])
        else:
            Q[-1][1]+=1
    return [q[1] for q in Q]

확실히 파이썬스럽다..

많이 쓰다 보면 나도 이렇게 파이썬 스러운 코드로 짤 수 있겠지

나와 로직 자체는 비슷한 것 같다.

이 분은 Q라는 list 에 [배포에 걸리는 일 수, 배포에 추가된 기능 수] 를 리스트로 추가했다.

그리고 Q[-1][0] (Q의 마지막 배포에 걸리는 일 수) 와 -((p-100)//s) 를 비교한다.

여기서 -1번째 인덱스를 쓴 것,

math 라이브러리를 쓰지 않고, 올림 연산을 하기 위해 음수로 몫 나누기 연산을 실행한 점,

zip 을 사용해서 효율을 높힌 점이 인상깊었다.

댓글