[프로그래머스] Lv.2 기능개발 (Python)

seulzzang·2022년 9월 14일
0

코딩테스트 연습

목록 보기
10/44

📍문제

[프로그래머스] Lv.2 기능개발

📍풀이

  • 남은 일수를 저장해줄 리스트 days와 남은 진도율을 저장해줄 remaining을 초기화 해준다. 이때 list assignment index out of range를 피해주기 위해서
days = [0]*len(progresses)
remaining = [0]*len(progresses)

이렇게 초기화. append쓸거면 그냥 빈 리스트로 나눠도 상관 없음.

  • 남은 일수를 구하기 위해서 다음과 같이 코드를 짜준다.
for i in range(len(progresses)):
    remaining[i] = 100-progresses[i]
    # 나누어 떨어지면 그 몫이 남은 날짜
    if remaining[i] % speeds[i] == 0:
        days[i] = remaining[i]/speeds[i]
    # 아니라면 몫+1일이 남은 날짜
    else:
        days[i] = (remaining[i]//speeds[i])+1

배포는 하루에 한번만 할 수 있으므로 정확하게 나누어 떨어지지 않으면 올림해준다는 의미에서 몫+1을 남은 날짜에 추가해준다. 어차피 progressesspeeds의 길이는 같으므로 range(len(progresses))라고 작성함

  • 이제 days에서, 현재 인덱스의 작업일 보다 큰 작업일이 나오면 배포개수를 추가해주는 작업을 거쳐주면 된다. 아래 전체 코드에서 확인!

💻코드

def solution(progresses, speeds):
    answer = []
    days = [0]*len(progresses) # 남은 일수
    remaining = [0]*len(progresses) # 남은 진도율
    
    # 남은 일수 구하기
    for i in range(len(progresses)):
        remaining[i] = 100-progresses[i]
        # 나누어 떨어지면 그 몫이 남은 날짜
        if remaining[i] % speeds[i] == 0:
            days[i] = remaining[i]/speeds[i]
        # 아니라면 몫+1일이 남은 날짜
        else:
            days[i] = (remaining[i]//speeds[i])+1
            
    index = 0
    for i in range(len(days)):
        if days[index] < days[i]: # 현재 인덱스의 작업일 보다 큰 작업일이 나오면
            answer.append(i-index) # 둘의 차이(배포개수) 를 추가
            index = i # 현재 인덱스를 갱신
    
    answer.append(len(days) - index)
    # 언젠가는 다 배포가 되니까 answer의 원소들의 합이 progresses의 원소 개수와 같아야함
	# 갱신된 인덱스부터 마지막 인덱스까지의 개수
    return answer

다른 사람 풀이를 참고하면 알겠지만 나는 너무 꼬아서 생각했다 ㄱ=
굳이 남은 일수로 지랄염병을 할 필요가 없었음. 그냥 딱 딱 직관적으로 생각했어야 했는데!!!

📍다른사람 풀이

첫번째

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]

솔직히 이건 진짜 이해가 안간다..; 근데 zip함수를 써서 계산이 쉽도록 한 점만 배워가기로 함..

두번째

def solution(progresses, speeds):
    answer = []
    time = 0
    count = 0
    while len(progresses)> 0:
        if (progresses[0] + time*speeds[0]) >= 100:
            progresses.pop(0)
            speeds.pop(0)
            count += 1
        else:
            if count > 0:
                answer.append(count)
                count = 0
            time += 1
    answer.append(count)
    return answer

첫번째 다른사람 풀이보다는 코드가 길지만 훨씬 직관적이고 이해하기 쉬운 코드이다.
time이 이제 작업일수.
문제에서 또, 각 기능의 개발속도는 모두 다르기 때문에 뒤에 있는 기능이 앞에 있는 기능보다 먼저 개발될 수 있고, 이때 뒤에 있는 기능은 앞에 있는 기능이 배포될 때 함께 배포됩니다.라고 했으므로 뒤에 있는 기능이 먼저 개발되어봤자 앞에 있는 기능이 배포되기 전에는 배포되지 못한다.
따라서 progresses[0]값을 계속 체크해주면서, 이것의 진도율이 100이 넘었다면 무조건 배포가 되니까 작업진도 리스트와 작업속도 리스트에서 삭제한 후 배포개수 count를 증가시켜준다.
만약 작업진도가 100이 넘지 않았는데 앞에서 배포할 작업이 있다면 answer에 현재 배포개수 count를 담아주고 초기화를 시켜준다. (해당날짜에 배포를 했다는 뜻으로) 이후 다음 날짜 작업을 확인하기 위해 time+=1 진행.
마지막 배포된 작업들에 대해서 append를 실행하지 않고 while문을 빠져나왔기 때문에 return위에서 answer.append(count)를 처리해줘야 한다.
time+=1else문에 걸려있다는 것을 확인하자.. else안의 if문에 걸려있는 것이 아니다!


기타

올림을 해주기 위해 math.ceil 올림함수를 사용하는 사람도 있었다. 해당 방법은 math모듈을 import해줘서 사용하면 된다. math모듈을 사용한걸 제외하면 나머지는 두번째 풀이와 비슷하게 해결한듯!

profile
중요한 것은 꺾이지 않는 마음

0개의 댓글