알고리즘🅰/프로그래머스

[프로그래머스] 기능개발

개발조각 2022. 3. 21. 13:43
728x90
반응형

이번 문제는 프로그래머스 Level 2 중에서 정말 쉬운 편에 속하는 것 같아요.

Level 2문제를 풀고 싶은데 어려워서 못 풀겠다 생각이 드시면 이문제부터 푸시는 것도 괜찮을 것 같아요.

 

 

저는 여기서 

progresses = [20, 99, 93, 30, 55, 10]
speeds = [5, 10, 1, 1, 30, 5]
Return = [3, 3]

추가했습니다.


해결방안

function solution(progresses, speeds) {
    var answer = [];
    
    let arr = progresses.map((pro,i) => Math.ceil((100-pro)/speeds[i]));
    
    let max = arr[0];
    let count = 0;
    for(let i=0; i<arr.length; i++){
        if(max >= arr[i]){
            count++;            
        }else{
            answer.push(count);
            max = arr[i]; 
            count = 1;
        }
        if(i === arr.length-1) answer.push(count);
    }    
    return answer;
}

 

해결방안 순서

  1. 각 작업의 기능 개발 완료 일 구해서 arr배열에 넣기
  2. 변수 max(?일), count(? 일에 몇 개의 기능이 완성됐는지) 기본값 설정하기
  3. for문으로 각 배포마다 몇 개의 기능이 배포되는지 answer배열에 담기

 

1단계. 각 작업의 기능 개발 완료 일 구해서 arr배열에 넣기

let arr = progresses.map((pro,i) => Math.ceil((100-pro)/speeds[i]));

기능의 진도가 100%일 때 서비스에 반영할 수 있다고 합니다.


기능이 93이면 93% 완료했다는 말이 되고
100% - 93% = 7%
7% 기능 작업을 해야지 서비스에 반영할 수 있게 됩니다.
이 7% 남은 기능작업을 하루에 1%씩 작업이 가능하다고 하면 총 7일 동안 작업을 해야 됩니다.

 

만약 기능이 30%가 완료되어 있고 하루에 30%씩 작업이 가능하다고 하면
100%-30% = 70%
70 / 30 = 2.3333....
이렇게 될 경우 2일이 아닌 3일간 작업 후 배포가 가능합니다.

 

위 예시를 토대로

작업의 기능 개발 완료일을 구하는 방법은

((100 - progresses[i]) / speeds[i]) 올림

이렇게 됩니다.

 

여기서 올림을 해주기 위해 Math.ceil() 함수를 사용했습니다.

코드로 작성하면 Math.ceil((100 - progresses[i]) / speeds[i]) 됩니다.

 

MDN Web Docs
Math.ceil() Math.ceil() 함수는 주어진 숫자보다 크거나 같은 숫자 중 가장 작은 숫자를 integer로 반환합니다.

문법 : Math.ceil(x)

  • x : 숫자

 

여기서 progresses배열 안에 있는 각 작업의 기능 개발 완료일을 배열에 담아주면

뒤에 단계 가서 for문 돌릴 때 편하지 않을까 해서

각 작업의 기능 개발 완료일을 arr배열에 담아주었습니다.

이때 map() 메서드를 사용해 주었습니다.

 

MDN Web Docs
map() 메서드는 배열 내의 모든 요소 각각에 대하여 주어진 함수를 호출한 결과를 모아 새로운 배열을 반환합니다.

구문 : arr.map(callback(currentValue[, index[, array]])[, thisArg])

  • callback : 새로운 배열 요소를 생성하는 함수. 다음 세 가지 인수를 가집니다.
  • currentValue : 처리할 현재 요소.
  • index Optional : 처리할 현재 요소의 인덱스.
  • array Optional : map()을 호출한 배열.
  • thisArg Optional : callback을 실행할 때 this로 사용되는 값.
// map()메서드 예제
const array1 = [1, 4, 9, 16];
const map1 = array1.map(x => x * 2);

console.log(map1); // map1 = [2, 8, 18, 32]

 

여기서는 progresses배열의 원소랑 speeds배열의 원소를 둘 다 사용해야 되기 때문에 

currentValue, index Optional을 적어주었습니다.

let arr = progresses.map((pro,i) => Math.ceil((100-pro)/speeds[i]));
테스트 1 progresses = [93, 30, 55] speeds = [1, 30, 5]
Math.ceil((100-pro)/speeds[i]) -> Math.ceil((100-93)/speeds[0]) -> Math.ceil((7/1) -> 7
arr  = [7]

Math.ceil((100-pro)/speeds[i]) -> Math.ceil((100-30)/speeds[1]) -> Math.ceil((70/30) -> Math.ceil(2.33...) -> 3
arr  = [7, 3]

Math.ceil((100-pro)/speeds[i]) -> Math.ceil((100-55)/speeds[2]) -> Math.ceil((45/5) -> 9
arr  = [7, 3, 9]

 

2단계. 변수 max(?일), count(? 일에 몇 개의 기능이 완성됐는지) 기본값 설정하기

let max = arr[0];
let count = 0;

for문을 돌리기 전에 max, count 변수의 기본값을 설정해 주었습니다.

 

이문제를 보시면

테스트 1 arr=[ 7, 3, 9 ]; return = [2, 1];
7
3
-------->7일까지는 2개의 기능 가능
9
-------->9일까지는 1개의 기능 가능

테스트 2 arr=[ 5, 10, 1, 1, 20, 1 ];  return = [1, 3, 2];
5
-------->5일까지는 1개의 기능 가능
10
1
1
-------->10일까지는 3개의 기능 가능
20
1
-------->20일까지는 2개의 기능 가능

(따로 추가한 거) 테스트 3 arr=[ 16, 1, 7, 70, 2, 18 ];  reurn = [3, 3]
16
1
7
-------->16일까지는 3개의 기능 가능
70
20
18
-------->70일까지는 3개의 기능 가능

위에 내용과 같이 특정 날 기준으로 기능을 몇 개 수행했는지 계산하게 됩니다.

특정 날이 더 커지면 교체가 되고요.

특정 날을 교체하기 위한 변수로 max를 사용해주었고요.

특정 날이 교제되기 전까지의 기능 가능한 횟수를 세는 변수로 count를 사용해주었습니다.

 

여기서 max변수의 초기값을 arr[0]으로 설정한 이유는요.

특정 날이 arr[0]부터 시작되어야 되기 때문입니다.

 

3단계. for문으로 각 배포마다 몇 개의 기능이 배포되는지 answer배열에 담기

for(let i=0; i<arr.length; i++){
    if(max >= arr[i]){
        count++;            
    }else{
        answer.push(count);
        max = arr[i]; 
        count = 1;
    }
    if(i === arr.length-1) answer.push(count);
}    
return answer;

위에서 만든 arr배열, max, count변수를 가지고 for문으로 돌렸습니다.

max가 arr[i]보다 크거나 같으면 count++을 해주었고요.

 

아닐경우 즉 max가 arr[i]보다 작을 경우

count값을 answer배열에 담아주고, max는 arr[i]로 교체, count는 1로 교체해 주었습니다.

여기서 count = 1로 교체한 이유는 max < arr[i] 상황에서 자기 자신을 세어야 되기 때문에 1로 넣어주었습니다.

 

마지막으로 i가 마지막이면 answer에 현재 count를 넣어주었습니다.

밑에 예시 보면 아시겠지만 마지막으로 반복할 차례일 때는 if else문에 해당이 안돼서

안 쓰면 마지막 자리값이 제대로 안 나와요.

 

잘 이해가 안 되시면 밑에 예시를 보세요.👇

테스트 2 arr=[ 5, 10, 1, 1, 20, 1 ]; 

max = arr[0] = 5;
count = 0;

i = 0
5 === max
-> count=1

i = 1
10 > max
-> answer.push(count); -> answer = [1];
-> max = arr[i]; -> max = arr[1]; -> max = 10
-> count = 1;

i = 2 
1 < max
-> count = 2

i = 3 
1 < max
-> count = 3

i = 4
20 > max
-> answer.push(count); -> answer = [1, 3];
-> max = arr[i]; -> max = arr[4]; -> max = 20
-> count = 1;

i = 5
1 < max
-> count = 2

if(i === arr.length-1) answer.push(count); -> answer.push(2); -> answer = [1, 3, 2];​

answer = [1, 3, 2];

여기까지 프로그래머스 기능개발 해결방안에 대해 설명해보았습니다.

728x90
반응형