문제 설명
프로그래머스 팀에서는 기능 개선 작업을 수행 중입니다. 각 기능은 진도가 100% 일 때 서비스에 반영할 수 있습니다.
또, 각 기능의 개발속도는 모두 다르기 때문에 뒤에 있는 기능이 앞에 있는 기능보다 먼저 개발될 수 있고, 이때 뒤에 있는 기능은 앞에 있는 기능이 배포될 때 함께 배포됩니다.
먼저 배포되어야 하는 순서대로 작업의 진도가 적힌 정수 배열 progresses와 각 작업의 개발 속도가 적힌 정수 배열 speeds가 주어질 때 각 배포마다 몇 개의 기능이 배포되는지를 return 하도록 solution 함수를 완성하세요.
제한사항
- 작업의 개수(progresses, speeds배열의 길이)는 100개 이하입니다.
- 작업 진도는 100 미만의 자연수입니다.
- 작업 속도는 100 이하의 자연수입니다.
- 배포는 하루에 한 번만 할 수 있으며, 하루의 끝에 이루어진다고 가정합니다. 예를 들어 진도율이 95%인 작업의 개발 속도가 하루에 4%라면 배포는 2일 뒤에 이루어집니다.
입출력 예
progresses | speeds | return |
[93, 30, 55] | [1, 30, 5] | [2, 1] |
[95, 90, 99, 99, 80, 99] | [1, 1, 1, 1, 1, 1] | [1, 3, 2] |
풀이
스택&큐에 해당하는 문제
const solution = (progresses, speeds) => {
let works = progresses.map((el,idx) => [el, speeds[idx]]);
let result = [];
while(works.length > 0){
works.forEach(el => el[0] += el[1]);
let deployWorks = 0;
for(let i = 0; i < works.length; i ++){
if(works[i][0] < 100) break;
else deployWorks ++;
}
works = works.slice(deployWorks);
result.push(deployWorks)
}
return result.filter(el => el > 0);
}
스택&큐란 간단하게 말하면 선입선출이냐 후입선출이냐로 생각하면 편하다.
이번 문제 같은 경우엔 선입선출인듯?
하루하루 지날 때마다 모든 작업 progress에 해당 작업의 speeds 만큼을 더해주고,
가장 첫 번째 작업이 진행률이 100%를 넘어가면 배포하는데,
순서대로 뒤에 있는 작업의 진행률을 체크해서 100면 배포할 때 같이 배포해줘야 한다.
그러니까 진행률이 100 90 95 100이고 모든 작업속도가 5일 때
첫날 첫 번째 작업 배포 [95, 100 , 100]
둘째 날 두 번째, 세 번째, 네 번째 작업 배포 이므로
결과 값은 [1, 3]이 나와야 한다.
전체적으로 코드를 풀어보면 우선
- works 변수를 만들어서 map()을 사용하여 [progress, speeds]의 모양의 2차원 배열을 만들어준다.
- 결과를 리턴하기 위한 result 변수를 만들어 빈배열로 초기화해둔다.
- 하루하루가 지나가는 걸 계산하기 위해 while문을 이용한다.
이때 조건은 works의 길이가 1 이상일 때 계속 반복되게 해 준다. - 반복문의 블록문 안에서는 우선 첫 번째로 works의 각 원소에서 progress,
0번째 원소에 speeds, 첫번째 원소의 값을 더해준다.
이후 배포된 작업의 개수를 체크하기 위해 deployWorks 변수를 0으로 초기화해주고
for문으로 각 작업의 progress가 100보다 낮으면 이후 반복문을 종료하기 위해
break 해준다. 그 외의 경우엔 deployWorks를 1 증가시켜주고
for문이 종료되면 works배열을 slice()를 이용해서 deployWorks 만큼 빠진 배열로 할당해 준 뒤,
result에 deployWorks를 push() 해준다. - while문이 종료되면 result에 filter() 매서드로 0인 값을 제외 한 뒤, 리턴해준다.
(지금 보니까 반복문 내에서 deployWorks가 0일 땐 push를 안 해주면 더 나을 듯하다.)