Level 2️⃣ - 기능개발

2024. 4. 3. 16:08알고리즘/프로그래머스

https://school.programmers.co.kr/learn/courses/30/lessons/42586

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

 

🚀문제 해석

작업 진도와 작업 속도가 데이터로 주어진다. 이 데이터를 가지고 작업 진도가 100퍼센트가 되는 날이 언제인지를 우선 구해야한다. 

그리고 앞의 작업이 배포된 후에 같이 배포할 수는 있어도 뒤의 작업이 먼저 끝났나고 앞의 작업보다 먼저 배포할 순 없다.

이 요구사항이 있기 때문에 큐를 활용해서 문제를 풀 수있다.

 

🛠코드

function solution(progresses, speeds) {
    const a = [];
    const ret = [];
    speeds.forEach((speed, idx)=>{
        let i = 1;
        while(progresses[idx] + (speed * i) < 100) i++;
        a.push(i);
    });
    let top = a[0];
    let i = 1;
    let cnt = 1;
    while(i < a.length){
        if(top >= a[i]) cnt++;
        else{
            ret.push(cnt);
            top = a[i];
            cnt = 1;
        }
        i++;
    }
    ret.push(cnt);
    return ret;
}

 

    speeds.forEach((speed, idx)=>{
        let i = 1;
        while(progresses[idx] + (speed * i) < 100) i++;
        a.push(i);
    });

이 코드는 작업이 100퍼센트 완료될 때까지 얼마나 걸리는지 계산하는 코드이다.

 

    let top = a[0];
    let i = 1;
    let cnt = 1;
    while(i < a.length){
        if(top >= a[i]) cnt++;
        else{
            ret.push(cnt);
            top = a[i];
            cnt = 1;
        }
        i++;
    }
    ret.push(cnt);
    return ret;

먼저 가장 앞에 있는 요소를 top으로 지정하고 top보다 작거나 같은 요소들은 모두 카운트를 해준다.

만일 top보다 큰 요소가 나온다면 그 요소를 다시 top으로 지정하고 카운트를 1로 초기화한다.

주의할 점은 while문을 다 돌고 마지막에 카운트한 것을 ret 배열에 푸시해야 마지막 배포된 갯수까지 추가할 수 있다.

이 부분이 조금 마음에 들지 않았다. 그냥 while문이 끝나면 추가 작업없이 정답을 리턴하고 싶었다.

 

다른 풀이

논리는 같으나 구현에 꽤나 차이가 있었다.

function solution(progresses, speeds) {
    let answer = [0];
    let days = progresses.map((progress, index) => Math.ceil((100 - progress) / speeds[index]));
    let maxDay = days[0];

    for(let i = 0, j = 0; i< days.length; i++){
        if(days[i] <= maxDay) {
            answer[j] += 1;
        } else {
            maxDay = days[i];
            answer[++j] = 1;
        }
    }

    return answer;
}

 

let days = progresses.map((progress, index) => Math.ceil((100 - progress) / speeds[index]));

이 코드는 작업이 완료될 때까지 얼마나 날짜가 걸리는지를 구하는 코드인데 Math.ceil을 사용한 이유는 문제 조건에서 배포는 하루에 한번만 이루어지며 하루의 끝에 이루어진다고 가정하기 때문이다.

 

function solution(progresses, speeds) {
    let answer = [0];
    let days = progresses.map((progress, index) => Math.ceil((100 - progress) / speeds[index]));
    let maxDay = days[0];

    for(let i = 0, j = 0; i< days.length; i++){
        if(days[i] <= maxDay) {
            answer[j] += 1;
        } else {
            maxDay = days[i];
            answer[++j] = 1;
        }
    }

    return answer;
}

 

 

그리고 maxDay를 days의 첫번째 요소 즉, 내가 구현한 코드에서는 top요소를 지정하는 것과 같다.

j 변수는 maxDay보다 작거나 같은 요소들을 카운팅하기 위한 변수인데 for문 안에 두 개의 변수를 활용해서 구현한 점이 인상깊었다.

카운팅을 전위 증감연산자를 사용해 초기화하는 것도 인상깊다.

 

다른 풀이를 보면서 더 쉽게 구현한 코드를 보면 더 열심히 하고 싶은 마음이 커지게 된다.

이 풀이도 나의 것으로 만들어야겠다는 다짐을 해본다.

'알고리즘 > 프로그래머스' 카테고리의 다른 글

Level 2️⃣ - 전화번호 목록  (1) 2024.04.05
Level 2️⃣ - 튜플  (0) 2024.04.03
Level 2️⃣ - H-Index  (0) 2024.04.03
Level 2️⃣ - n^2 배열 자르기  (0) 2024.04.03
Level 2️⃣ - 괄호 회전하기  (0) 2024.04.02