몸과 마음이 건전한 SW 개발자

프로그래머스 [Lv. 2] 과제 진행하기 {언어 : JavaScript} 본문

알고리즘

프로그래머스 [Lv. 2] 과제 진행하기 {언어 : JavaScript}

스위태니 2024. 4. 8. 18:23

문제 링크

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

 

프로그래머스

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

programmers.co.kr

정답 코드

function solution(plans) {
    const lenP = plans.length - 1;
    const answer = [];
    let stack = [];
    // 시작 시간으로 정렬
    const sortedP = plans.map(([n, s, p]) => {
        const [sh, sm] = s.split(":");
        return [n, Number(sh)*60+Number(sm), Number(p)];
    });
    sortedP.sort(([n1, s1, p1], [n2, s2, p2]) => s1 - s2);
    while (sortedP.length) {
        const [cn, cs, cp] = sortedP.shift();
        const cscp = cs + cp;
        if (sortedP.length) {
            const [nn, ns, np] = sortedP[0];
            if (cscp <= ns) {
                answer.push(cn);
                let nscscp = ns - cscp;
                if (nscscp) {
                    while (stack.length) {
                        const lenS = stack.length;
                        const [sn, ss, sp] = stack[lenS-1];
                        if (sp <= nscscp) {
                            answer.push(sn);
                            stack.pop();
                            nscscp -= sp;
                        } else {
                            stack[lenS-1][1] += nscscp;
                            stack[lenS-1][2] -= nscscp;
                            break;
                        };
                    };
                };
            } else {
                stack.push([cn, ns, cscp-ns]);
            };
        } else {
            answer.push(cn);
            while (stack.length) {
                const [sn, ss, sp] = stack.pop();
                answer.push(sn);
            };
        };
    };
    return answer;
}

풀이 방법

  1. 계산에 용이하기 위해 시간을 분으로 바꾼다.
    1. 예를들어 12:00 => 12*60 = 720분
  2. 이제 시작 시간 순으로 정렬한다.
  3. 정렬한 배열을 하나씩 뺀다.
    1. 하나를 빼고 나서 sortedP의 길이가 0이라면
      1. 현재 과제 이름을 answer에 넣고
      2. 나머지를 모두 pop하면서 answer에 저장한다.
    2. 0이 아니라면 다음 요소를 확인한다.
      1. 현재시간에 과제를 수행하는데 걸린 시간을 더한 값 = cscp와 다음 시작시간을 비교한다.
        1. 다음 시작 시간보다 cscp의 값이 작다는 말은 시작하기도 전에 끝낸다는 말이므로 answer에 이름을 넣는다.
          1. cscp값과 다음 시작시간까지 얼마나 시간이 남았는지 확인한다 = nscscp
            1. nscscp값이 0보다 크다면 남는 시간동안 stack에 있는 요소들을 확인하며 끝낼 수 있는 것들은 끝내고 answer에 집어넣는다.
            2. 끝내지 못했을 경우에는 stack에 마지막 요소에서 수행하는데 걸리는 시간에서 nscscp값을 빼주고 현재 시각에 nscscp값을 더해준다.
        2. cscp값보다 작다면
          1. stack에 현재 요소를 넣는다.
  4. 마지막으로 answer를 출력한다.

느낀점

  • 머리가 잘 안돌아갈 때는 풀기 어려운 문제 같다.