본문 바로가기
알고리즘

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

by 블쭌 2021. 3. 3.
728x90
  • 문제 설명

프로그래머스 팀에서는 기능 개선 작업을 수행 중입니다. 각 기능은 진도가 100%일 때 서비스에 반영할 수 있습니다.

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

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


  • 제한 사항
    • 작업의 개수(progresses, speeds배열의 길이)는 100개 이하입니다.
    • 작업 진도는 100 미만의 자연수입니다.
    • 작업 속도는 100 이하의 자연수입니다.
    • 배포는 하루에 한 번만 할 수 있으며, 하루의 끝에 이루어진다고 가정합니다. 예를 들어 진도율이 95%인 작업의 개발 속도가 하루에 4%라면 배포는 2일 뒤에 이루어집니다.

  • 입/출력
progresses speeds result
[93, 30, 55] [1, 30, 5] [2, 1]
[95, 90, 99, 99, 80, 99] [1, 1, 1, 1, 1, 1] [1, 3, 2]

  • 코드
def solution(progresses, speeds):
    answer = []
    
    res = []
    for p, s in zip(progresses, speeds):
        q, r = divmod((100-p), s)
        res.append(q if r == 0 else q+1)
        
    while res:
        temp = res.pop(0)
        count = 1
        while res and temp >= res[0]:
            res.pop(0)
            count += 1
        
        answer.append(count)
    
    return answer

나는 나머지 잔여일을 구하고 이후 해당 값이 다음값보다 작을때까지 count를 1씩 증가시켜 마지막에 append를 해주었다. 물론 통과는 했지만 for문 한번에 while문에 while문이 다시 들어가면서 다른 사람에 비해서 효율적인 코드는 아니었다.

 

def solution(progresses, speeds):
    answer = []
    
    res = []
    for p, s in zip(progresses, speeds):
        q, r = divmod((100-p), s)
        res.append(q if r == 0 else q+1)
    
    print(res)
    count = 1
    for i in range(len(res)):
        try:
            if res[i] < res[i + 1]:
                print(res[i], res[i+1], count)
                answer.append(count)
                count = 1
            else:
                print(res[i], res[i+1], count)
                res[i + 1] = res[i]
                count += 1
                print(res)
        except IndexError:
            answer.append(count)

    
    return answer

똑같이 잔여일을 구한 이후에 for문을 1번만썼다. 위에는 while문 2번...

이는 try except를 사용해서 현재 index랑 다음 index를 비교해서 현재 index의 값이 더 작으면 해당일을 마무리했기 때문에 바로 append해주고 값이 더 크다면 해당 값을 다음 값으로 update해서 작을떄까지 비교한다. 해당값을 다음값으로 바꿔주는 이유는 그 값이 기준점이 되어서 그 값보다 작은 경우에 배포가 한번에 가능하기 때문이다. 기준점을 계속 가줘가기 위해서 해준다고 생각하면 편할것같다.

또한 except가 들어가는 이유는 마지막 index는 다음 index가 없기 때문에 예외처리를 해주지 않으면 런타임 에러가 나기 때문이다.

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

	return [i[1] for i in answer]

정말 대단한 코드이다.. for문 1줄로 처리!

이는 위에서 잔여시간만 구했지만 이는 잔여시간과 동시에 바로 값을 update했다.

 

(100-p)//s를 하게되면 나머지가 0이냐 아니냐에 따라서 1을 추가해줘야하는데 -를 붙이면 그런점을 고려할 필요가 없다는것까지 알게되었다.. (다들 유용하게 사용하시길..!!)

 

이는 현재 answer의 배열에 값이 없는 경우 또는 answer배열의 마지막 값의 남은 잔여시간이 그 다음 잔여시간보다 작다면 바로 [해당 잔여시간, 1]을 추가시켜준다

반대로 남은 잔여시간이 그 다음 잔여시간보다 크다면 한번에 배포가 가능하기때문에 위에서 추가했던 2번째 값에 1을 추가시켜준다


  • 출처

programmers.co.kr/learn/courses/30/lessons/42586

728x90

댓글