프로그래머스 팀에서는 기능 개선 작업을 수행 중입니다. 각 기능은 진도가 100%일 때 서비스에 반영할 수 있습니다.
또, 각 기능의 개발속도는 모두 다르기 때문에 뒤에 있는 기능이 앞에 있는 기능보다 먼저 개발될 수 있고, 이때 뒤에 있는 기능은 앞에 있는 기능이 배포될 때 함께 배포됩니다.
먼저 배포되어야 하는 순서대로 작업의 진도가 적힌 정수 배열 progresses와 각 작업의 개발 속도가 적힌 정수 배열 speeds가 주어질 때 각 배포마다 몇 개의 기능이 배포되는지를 return 하도록 solution 함수를 완성하세요.
- 작업의 개수(progresses, speeds배열의 길이)는 100개 이하입니다.
- 작업 진도는 100 미만의 자연수입니다.
- 작업 속도는 100 이하의 자연수입니다.
- 배포는 하루에 한 번만 할 수 있으며, 하루의 끝에 이루어진다고 가정합니다. 예를 들어 진도율이 95%인 작업의 개발 속도가 하루에 4%라면 배포는 2일 뒤에 이루어집니다.
① 입출력 예
② 입출력 예 설명
입출력 예 #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개의 기능이 배포됩니다.
이 문제에 대한 해설의 경우 진행 순서를 넘버링으로 매겼습니다.
아래의 코드를 살펴 보시면서 1번 설명부터 보시고, 2번 설명 및 다음 설명을 참조하시면 감사하겠습니다.
function solution(progresses, speeds) {
let answer = [];
let rate = [];
let i, j, k;
let p = 0, sum = 0, count;
for(j = 1; !(sum === progresses.length); j++){
// ② 다시 돌아와 이번에는 sum이 2이기 때문에 조건식이 true(!로 인해 변환)이므로 for문을 계속 실행합니다.
// ③ 이제 sum은 3이므로 반복 조건의 값은 false가 되기 때문에(3 === 3의 결과는 true에 not 연산자가 붙어 false가 됩니다.) for문을 종료합니다.
sum = 0;
// ② sum을 초기화 해준 후
for(i = 0; i < progresses.length; i++){
rate[i] = progresses[i] + j * speeds[i];
}
// (공통) rate 배열에 각 진행 상황에 하루(j)의 속도(speeds)를 곱한 값을 저장합니다. 즉 j는 날짜가 될것이고 rate(진행율) 에는 j(날짜)가 증가 할 때마다 그에 따른 각 프로그램의 진행 상태가 증가될 것입니다.
count = 0;
// ① count값, 즉 앞선 프로그램이 끝나는 때와, 그 뒤에 이미 끝나있는 프로그램을 합산할 변수를 선언합니다.
// ② count를 초기화 한 후
// ① 아래의 if 조건문은 rate의 [p] 번째(현재는 0, 즉 진행율의 처음 값)가 100 이상일 경우 실행하고 그게 아니라면 아래의 for문을 거쳐 계속 j(날짜)를 증가시켜가며 다시 처음 for문을 수행할거기 때문에 그때마다 rate를 새로 갱신하다가 rate의 처음 값이 100이 되는 시점의 배열인 [100,240,90] 가 rate에 할당되면 아래의 if문 조건이 발동됩니다.
// ② rate의 배열 중 첫번째 값과 두번째 값은 100을 넘긴 상태에서 계속 증가를 하겠지만 세번째 값은 아직 95 이므로 아래의 if 조건문(rate[2], 즉 세번째 프로그램의 달성율이 100을 넘기지 못한 상태)에 부합하지 못하고 또 j가 9일때 100을 달성하게 됩니다.
if(rate[p] >= 100) {
// ① 만약 rate의 처음값이 100이상, 즉 100을 달성하면
// ② 이제 rate의 세번째 값 또한 100을 달성하였고
while(rate[p] >= 100){
// ① 그 값이 100 이상인 경우, 즉 rate의 달성도가 100 이상인 동안에 while문을 활성화 하면서 아래의 코드들을 실행하는데, rate가 세번째를 가리키는 때(세번째 프로그램의 진행도가 90일때 ) while문에 부합하지 못하므로 while문을 빠져나옵니다.
count++;
// ① 달성한 프로그램의 수를 의미하는 count값을 증가시켜준 후
// ② 초기화 한 count값을 다시 1로 증가시킨 후
p++;
// ① rate의 인덱스 이동을 위해 p를 증가시켜줍니다.
// ② p를 증가 시키는데
if (p === rate.length){
// ② p(최종 완료된 프로그램 값)이 rate의 진행율의 길이, 즉 모든 프로그램이 100을 달성한 때에 while문을 종료합니다.
break;
}
}
answer.push(count);
// ① 그럼 count에는 2가 저장이 되어있을텐데, 그 값을 answer 배열의 첫번째에 넣어줍니다.
// ② 마찬가지로 저장 되어있는 count(1) 값을 answer에 할당 해주고
}
for(k = 0; k < answer.length; k++){
sum = sum + answer[k];
}
// ① 다시 돌아와 k가 answer 배열, 즉 1까지 증가시키며 sum에 answer의 k값을 누적 합산 시켜줍니다. 이 경우 answer 배열의 길이는 1이므로 딱 한번 발동 되는데 sum에는 아무것도 안들어 있으므로 sum의 누적 합산 결과는 2가 됩니다.
// ② 이제 k는 answer의 길이만큼, 즉 [2,1]이 들어있으므로 두 번 반복을 할텐데, sum은 현재 0이 들어있는 상태이므로 2와 1를 담아 3이 됩니다.
}
return answer;
// ③ for문 종료 후 answer 값([2,1])을 반환합니다.
}