루나의 TIL 기술 블로그

프로그래머스 level 2 기능개발, 스택/큐

|

걸린 시간 : 3시간?

문제 설명

프로그래머스 팀에서는 기능 개선 작업을 수행 중입니다. 각 기능은 진도가 100%일 때 서비스에 반영할 수 있습니다. 각 기능의 개발속도는 모두 다르기 때문에 뒤에 있는 기능이 앞에 있는 기능보다 먼저 개발될 수 있고, 이때 뒤에 있는 기능은 앞에 있는 기능이 배포될 때 함께 배포됩니다.

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

입출력 예 #1 첫 번째 기능은 93% 완료되어 있고 하루에 1%씩 작업이 가능하므로 7일간 작업 후 배포가 가능합니다. 두 번째 기능은 30%가 완료되어 있고 하루에 30%씩 작업이 가능하므로 3일간 작업 후 배포가 가능합니다. 하지만 이전 첫 번째 기능이 아직 완성된 상태가 아니기 때문에 첫 번째 기능이 배포되는 7일째 배포됩니다. 세 번째 기능은 55%가 완료되어 있고 하루에 5%씩 작업이 가능하므로 9일간 작업 후 배포가 가능합니다.

따라서 7일째에 2개의 기능, 9일째에 1개의 기능이 배포됩니다.

입출력 예 #2 모든 기능이 하루에 1%씩 작업이 가능하므로, 작업이 끝나기까지 남은 일수는 각각 5일, 10일, 1일, 1일, 20일, 1일입니다. 어떤 기능이 먼저 완성되었더라도 앞에 있는 모든 기능이 완성되지 않으면 배포가 불가능합니다.

따라서 5일째에 1개의 기능, 10일째에 3개의 기능, 20일째에 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]

사고 과정

for문을 돌려서 progresses[i] +speeds[i]을 실행하고, progresses[0]이 100을 넘으면 pop해서 리스트에서 꺼낸다. for문에 count를 증가시켜서 count를 출력한다.
100%가 넘어서 배포되는 것들을 어떻게 나누어서 리스트로 출력할지는 잘 모르겠다.

def solution(progresses, speed):
    count = 0

    while len(progresses)>0: #프로그래스 리스트가 텅 빌때까지
        for i in range(0,len(progresses)): #len(progresses)는 3
            a = progresses[i]+speed[i]
            progresses.pop(0)
            progresses.insert(0, a) 
            #프로그레스에 스피드를 더한 값을 프로그레스 앞에 넣는다
            print(progresses)
            if progresses[0]>=100: #100이상이면 
                progresses.pop(0) #리스트에서 제거한다
                speed.pop(0)            
            count += 1
            #100%가 넘어서 배포되는 것들을 어떻게 나누어서 리스트를 출력할지 잘 모르겠다.
    print(count)
    return count

solution([93,30,55],[1,30,5])

처음에는 progresses[i] = progresses[i]+speed[i]했는데 인트형=인트형이라 그런지 작동하지 않았다.
progresses.insert(0, progresses[i]+speed[i]) 이렇게 인서트를 써도
IndexError: list index out of range 에러가 난다.
리스트에서 인덱스가 없는걸 찾으면 나는 에러라고 하는데 왜 나는건지 잘 모르겠다.

그래서 이렇게 바꿔보았더니

a = progresses[i]+speed[i] # a = 94 
progresses.pop(0) # progresses = [30,55]
progresses.insert(0, a) # progresses = [94,30,55]

print(a)를 했더니 계속 60이 나왔다. i에 0이 아닌 1이 들어가서 그런줄 알았는데 그게 아니고 while루프가 무한반복되는걸 내가 중간에 멈춰서 콘솔창의 결과값이 맨 앞부터 안 보이는 것 같았다. 디버깅할 때 무한루프를 돌지 않도록 해놓고 봐야겠다.

def solution(progresses, speed):
    count1 = 1
    count2 = 0
    while len(progresses)>0: #프로그래스 리스트가 텅 빌때까지
    #for i in range(len(progresses)): #i에 0,1,2대입
        a = progresses[0]+speed[0]*count1
        progresses.pop(0)
        progresses.insert(0,a)
        print(progresses)

        if progresses[0]>= 100:
            progresses.pop(0)
            speed.pop(0)
            count1 += 1
            count2 += 1
        else:
            count1 += 1
    
    print(count1)
    print(count2)
    return count2

solution([93,30,55],[1,30,5])

이것저것 해보다가 결국 for문에서 i를 이용해서 풀지 못할 것 같아서 for문은 지웠다. 모범답안에서 나온대로 progresses[0]을 사용해서 풀어보려고 했다. 위 코드를 돌리면 콘솔 창에 아래와 같이 나온다.

[94, 30, 55]
[96, 30, 55]
[99, 30, 55]
[103, 30, 55]
[180, 55]
[85]
[120]
8
3

시간이 너무 오래걸려서 이정도에서 포기했다!

모범 답안

def solution(progresses, speeds):
    answer = []
    time = 0
    count = 0
    while len(progresses)>0:
        if(progresses[0]+time*speeds[0]) >= 100:
            #완료된 퍼센트 + 작업일수*하루작업량이 100이 넘으면
            progresses.pop(0) #리스트[0]제거
            speeds.pop(0)
            count+=1 #카운트 올라감
        else: #100이 넘지 않으면 타임+1한 뒤 다시 돌아감
            if count >0: #100이 넘지 않았는데 카운트가 있으면
                answer.append(count) #카운트를 리스트에 추가
                count = 0 #카운트를 리셋
            time+=1
    answer.append(count)
    #카운트를 리스트에 추가
    return answer

time을 while문 안에 돌려서 날짜가 더해지면 %가 올라가는 것을 구현해준 것이 좋았다.
if else로 나누어서 100이 넘지 않으면 time이 하나 더해지는 것이 좋다.

while 조건
    if 조건 
        반복하고싶은 내용
        count+=1 
    else
        count를 답에 추가하고 리셋
        time+=1
count를 답에 추가

이런 구조를 생각하지 못했다!

주요 포인트 및 생각해볼 점

level2가 되면서 난이도가 급격하게 어려워지는 것 같은건 내 실력이 부족한 탓이겠지?