프로그래머스 LV2 #7 기능 개발

Jake Seo·2020년 8월 2일
0

프로그래머스 LV2

목록 보기
7/10

프로그래머스 LV2 #7 기능 개발

문제

풀이

문제를 보며 수식을 작성하는게 핵심입니다.

먼저 작업과 속도를 기준으로 총 며칠이 걸리는지 파악하는 수식이 중요한데,

총 100%의 작업량이 필요하므로 (100-현재 작업량) / 작업 속도라는 수식으로 며칠동안 작업을 해야하는지 구할 수 있습니다. 여기서 주의할 점은 입출력 예의 2번째 케이스입니다.

입출력 예 에서의 2번째 작업의 케이스를 보면 30% 개발된 상태에서 30%의 작업속도로 3일을 진행해야 2번째 작업이 끝납니다. 사실 30%의 작업속도로 3일을 일하면 120%의 작업이 가능하지만 20%는 버려지고 그냥 100%의 작업이 되었다고 보는 것입니다.

위의 말을 달리 하면 아무리 적은 양의 작업 이를테면 39%의 작업을 30%의 속도로 해서 두번째 날에 1%가 남는다고 해도 작업을 하는데는 3일이 걸린다는 말이 됩니다.

그래서 여기서 Math.ceil이 필요함을 유추할 수 있습니다. 그래서 전체 수식은 Math.ceil((100-현재 작업량) / 작업 속도)가 됩니다.

어차피 모든 작업에 대해 며칠의 작업이 남았는지 구해야 하므로 모든 작업에 대해 Map 메소드로 순회해줍니다.

progresses.map((p, i) => {
	let requiredTime = Math.ceil((100 - p) / speeds[i]);
});

위와 같이 시작할 수 있습니다.

그리고 문제를 잘 보면, 작업은 병렬적으로 이루어지지만, 이후의 작업이 아무리 빨리 완료되어도 선행 작업이 완료되는 시점에만 반영이 가능합니다.

이를테면 1번, 2번, 3번의 작업이 있는데 2번, 3번 작업이 아무리 빨리 완료되어도 1번의 작업이 완료되기 전까지는 반영될 수 없습니다.

위와 같은 조건을 if문으로 표현하면 다음과 같습니다.

let waitingTasks = [];

if(Math.max(...waitingTasks) >= requiredTime){
	waitingTasks.push(requiredTime);  
}

위의 ifpush가 뜻하는 것은 만일 이후에 완료된 작업이 이전 작업의 작업시간보다 작거나 같았다면 한 번에 처리하도록 일단 쌓아놓는 것을 의미합니다.

그런데 쌓아놓는 경우는 사실 한 가지가 더 있습니다. 대기중인 작업이 아무것도 없을 때도 쌓아야 합니다.

let waitingTasks = [];

if(waitingTasks.length === 0 || Math.max(...waitingTasks) >= requiredTime){
	waitingTasks.push(requiredTime);  
}

위와 같이 코드가 완성됩니다.

만일 쌓는 경우가 아니라면 한 번에 반영을 해주고 몇 개의 기능이 반영되었는지 정답에 반영해주어야 합니다. 그 부분을 코드로 반영하면 다음과 같습니다.

let waitingTasks = [];
let answer = [];

if(waitingTasks.length === 0 || Math.max(...waitingTasks) >= requiredTime){
  waitingTasks.push(requiredTime);  
}else {
  answer.push(waitingTasks.length);
  waitingTasks = [];
  waitingTasks = waitingTasks.push(requiredTime);
}

위와 같이 작성됩니다.

사실 waitingTasks에 대한 작업들은 다음과 같이 축약될 수도 있습니다.

let waitingTasks = [];
let answer = [];

if(waitingTasks.length === 0 || Math.max(...waitingTasks) >= requiredTime){
  waitingTasks.push(requiredTime);  
}else {
  answer.push(waitingTasks.length);
  waitingTasks = [requiredTime];
}

그리고 마지막에 map 메소드에서 쌓으며 끝났을 수도 있기 때문에 작업 스택에 무엇이 있는지 확인하고 넣어주는 작업이 한번 필요합니다.

let waitingTasks = [];
let answer = [];

if(waitingTasks.length === 0 || Math.max(...waitingTasks) >= requiredTime){
  waitingTasks.push(requiredTime);  
}else {
  answer.push(waitingTasks.length);
  waitingTasks = [requiredTime];
}

if(waitingTasks.length > 0){
  answer.push(waitingTasks.length);
}

마지막으로 정답 코드를 작성하면 다음과 같습니다.

let solution = (progresses, speeds) => {
  let waitingTasks = [];
  let answer = [];

  progresses.map((p, i) => {
    let requiredTime = Math.ceil((100 - p) / speeds[i]);

    if(waitingTasks.length === 0 || Math.max(...waitingTasks) >= requiredTime){
      waitingTasks.push(requiredTime);
    }else {
      answer.push(waitingTasks.length);
      waitingTasks = [requiredTime];
    }      
  });

  if(waitingTasks.length > 0){
    answer.push(waitingTasks.length);
  }

  return answer;
};

끝.

profile
풀스택 웹개발자로 일하고 있는 Jake Seo입니다. 주로 Jake Seo라는 닉네임을 많이 씁니다. 프론트엔드: Javascript, React 백엔드: Spring Framework에 관심이 있습니다.

0개의 댓글