문제설명
프로그래머스 팀에서는 기능 개선 작업을 수행 중입니다. 각 기능은 진도가 100%일 때 서비스에 반영할 수 있습니다.
또, 각 기능의 개발속도는 모두 다르기 때문에 뒤에 있는 기능이 앞에 있는 기능보다 먼저 개발될 수 있고, 이때 뒤에 있는 기능은 앞에 있는 기능이 배포될 때 함께 배포됩니다.
먼저 배포되어야 하는 순서대로 작업의 진도가 적힌 정수 배열 progresses와 각 작업의 개발 속도가 적힌 정수 배열 speeds가 주어질 때 각 배포마다 몇 개의 기능이 배포되는지를 return 하도록 solution 함수를 완성하세요.
제한 사항
- 작업의 개수(progresses, speeds배열의 길이)는 100개 이하입니다.
- 작업 진도는 100 미만의 자연수입니다.
- 작업 속도는 100 이하의 자연수입니다.
- 배포는 하루에 한 번만 할 수 있으며, 하루의 끝에 이루어진다고 가정합니다. - 예를 들어 진도율이 95%인 작업의 개발 속도가 하루에 4%라면 배포는 2일 뒤에 이루어집니다.
접근 방법
문제를 읽고나서, 원하는 answer 배열을 얻기 위해선 가장먼저 두 가지 문제를 해결해야 한다 생각했다.
1. 기능 개발 배포까지 걸리는 일수를 계산해야 한다.
2. 맨 앞 원소부터 기능 개발 일수를 누적해 비교하고 출력해야 한다.
위와 같이 생각하고나서 문제 풀이를 진행했다.
def solution(progresses, speeds):
answer = []
days = []
tmp = 1
for i in range(len(progresses)):
days.append(( - 100 + progresses[i])//speeds[i] * -1)
for i in range(len(days)- 1) :
print(days[i:i+1], days[i+1:i+2])
if days[i:i+1] < days[i+1:i+2] :
answer.append(tmp)
tmp = 1
else:
tmp += 1
# 가장 마지막 작업은 그냥 append
answer.append(tmp)
return answer
# i번째 작업보다 i+1번째 작업의 개발시간이 크다면 선행한 작업을 바로 배포한다.
# 만약 i+1번째 작업의 개발시간이 적다면 선행 배포시 함께 배포한다.
처음 시도한 코드는 다음과 같이 돌아가도록 생각하며 작성했다.
1. days
배열을 만들어서, 각 작업의 개발 시간을 기록한다.
2. 만들어진 days
에서 아이템을 두개씩 뽑아, 더 큰 개발시간이 필요한 작업이 있다면, 선행 작업을 먼저 배포한다.
3. 지금 작업이 뒷 작업보다 더 큰 개발시간이 필요하다면, 뒤따르는 기능도 한 번에 배포한다.
def solution(progresses, speeds):
n = len(progresses)
answer = []
days = []
tmp = 1 # 기능 개발은 무조건 1개는 배포
for i in range(n):
days.append(( - 100 + progresses[i])//speeds[i] * -1)
# 인덱스로 조작
idx = 0
for i in range(1,n):
if days[i] > days[idx]:
answer.append(i - idx)
idx = i
# 가장 마지막 작업은 그냥 append
answer.append(n-idx)
return answer
추가적으로 다른 아이디어를 찾아보았다. 구글링에서 높은 순위로 나온 블로그의 풀이를 참고하여 보니, progresses
와 speeds
를 큐로 써서, progresses
의 원소를 돌릴 때, 각각의 원소에 speeds를 더해가면서 맨 앞 원소가 100을 넘었을 때, 100이상의 원소들을 한 번에 배포한다.
def solution(progresses, speeds):
n = len(progresses)
answer = []
while progresses:
cnt = 0
# 가장 먼저 개발하고 있는 기능을 다 개발하자
while progresses[0] < 100:
progresses = [p + s for p, s in zip(progresses, speeds)]
# 각 기능의 개발 척도가 100을 넘었는지 확인
for i in progresses:
if i >= 100:
cnt += 1
else:
break
# 기능 배포 시점. 뒤따르는 개발 진행 상황을 새로 카피한다.
progresses = progresses[cnt:]
speeds = speeds[cnt:]
answer.append(cnt)
return answer
첫 주석 라인에서 볼 수 있듯, zip 연산을 통해 가장 먼저 개발하고 있는 progresses[0]
이 100이 넘을 때까지 전체 개발을 진핼한다.
두번째 주석에선 첫번째 기능이 배포될 때 progresses 배열내에 배포할 수 있는 다른 기능이 있는지 확인한다. 없다면 break하고, 다음 기능부터 개발 상황을 다시 확인하기 시작한다.
++ 아무리 오랜만에 코테 공부를 한다해도 너무 오랜만인지 웬만한 파이썬 문법도 알고리즘도 다 잊어버렸다.. 복습 빡시게 해야지!