기능개발(programmers 문제) python 풀이

Jipoleon·2021년 7월 25일
0

programmers

목록 보기
8/9
post-thumbnail

문제 링크: https://programmers.co.kr/learn/courses/30/lessons/42586

입력으로 두 개의 정수 배열이 들어온다.

첫 번째 배열은 각 작업별 기능 개발의 진행률을 담은 배열인 progresses이고,
두 번째 배열은 각 작업별 기능 개발의 속도가 적힌 배열인 speeds이다.

예를 들어 인풋으로

progresses = [93, 30, 55]
speeds = [1, 30, 5]

가 들어왔다고 가정을 하면, 첫 번째 기능은 현재 93%가 개발되어 있고 매일 1%씩 작업이 가능하다. n일이 지났으면 첫 번째 기능은 (93 + n)% 만큼 개발이 된 것이며, 두 번째와 세 번째 작업은 각각 (30 + 30n)%, (55 + 5n)% 만큼 개발이 된 것이다.

각 기능이 개발이 100% 이상이 되었을 때 배포를 할 수 있는데, 이때 중요한 조건이 있다.

앞의 기능이 모두 개발 완료가 되어야 뒤의 기능도 배포가 가능하다는 것이다.

앞의 예시를 다시 보면 두 번째 작업은 작업률이 무려 30%이기 때문에 3일 뒤 작업률이 100%가 넘어 배포가 가능하다. 하지만, 첫 번째 작업이 개발 완료가 되려면 7일을 기다려야 하기 때문에 첫 번째 배포일은 3일이 아니라 7일이 된다.

우리가 리턴해줘야 하는 값은 몇 번째 배포일마다 몇 개의 기능을 배포하는지 배열로 넣어서 리턴해줘야 한다. 즉, 위의 예시는 [2, 1]을 리턴해줘야 정답이 된다.

내 풀이

1. 첫 번째

내 알고리즘은 이러했다.
"앞에 있는 작업이 먼저 끝나야지만 뒤에 있는 작업이 끝나기 때문에 계속 작업을 반복하는데 만일 맨 앞에 있는 작업이 100%가 넘을 경우, 맨 앞에 있는 작업부터 100% 미만인 작업이 나올 때까지 해당 배열의 값을 제거하고, 다시 작업을 진행하여 이 작업을 반복한다."

def solution(progresses, speeds):
    answer = []
    
    while True:
        progresses = [p+s for p,s in zip(progresses, speeds)]
        if progresses[0] >= 100:
            progresses, speeds, num_distribute = distribute(progresses, speeds)
            answer.append(num_distribute)
            if len(progresses) == 0:
                break
    
    return answer

def distribute(progresses, speeds):
    num_distribute = 0
    
    for idx in range(len(progresses)):
        if progresses[idx] >= 100:
            num_distribute += 1
            
        else:
            break
    
    del progresses[:num_distribute]
    del speeds[:num_distribute]
    
    return progresses, speeds, num_distribute

따라서 위의 코드에서 볼 수 있듯이 하루가 지날 때마다 progresses의 각 인덱스가 각 날의 진행률을 담은 speeds의 각 인덱스만큼 증가하기 때문에 progresses 배열 + speeds 배열을 만들었다.

배열의 인덱스끼리 더하는 방법은 내가 알기론 아래와 같이 세 가지 방법이 있는데, 난 첫 번째 방법을 선택했다.

# 두 개의 배열 선언
a = [1, 2, 3]
b = [4, 5, 6]

# 첫 번째 방법
c = [x+y for x,y in zip(a,b)]

# 두 번째 방법
c = [a[i]+b[i] for i in range(len(a))]

# 세 번째 방법
c = [aa+bb for aa in a for bb in b]

print(c) # => [5, 7, 9]

단, 위의 배열의 합 코드 들은 배열의 길이가 같을 때 사용 가능하다.

다음으로 if 문을 사용해 맨 앞에 있는 작업의 진행률이 100% 이상인지 확인하고 100% 이상인 경우 distribute 함수를 호출한다.

distribute 함수는 인자값으로 progresses와 speeds를 받아서, 작업률이 100% 미만인 인덱스가 나올 때까지 num_distribute를 더해준다. 이것은 즉, 한번에 몇개를 유통할지 구하는 부분이다. 그리고 몇 개를 유통할지 구하면 그 앞에 있는 부분은 del을 이용해 제거해준다.

이 작업을 반복하면 정답이 나온다.

결과

한번에 모두 통과했다!

다른 사람 풀이

import math

def solution(progresses, speeds):
    answer = []
    work_day = [math.ceil((100-a)/b) for a, b in zip(progresses, speeds)]
    front = 0
    for idx in range(len(work_day)):
        if work_day[front] < work_day[idx]:
            answer.append(idx-front)
            front = idx
    answer.append(len(work_day)-front)
    return answer

다른 사람의 풀이를 봤는데, math를 import 해와서 ceil함수를 사용해 각 작업을 끝내려면 얼마나 걸리는지를 work_day라는 배열안에 넣었다.
그리고 work_day안에 있는 배열을 통해 앞의 작업과 비교해 answer에 append를 진행하고 리턴을 해줬다.

결과

근데, 문제가 개편이 되어서 테스트 11을 통과하지 못했다.

profile
I Love AI

0개의 댓글