프로그래머스 LEVEL 2(과제 진행하기)

image

  • 사용 언어 : javascript

  • 해결 날짜 : 2023-05-11

  • 해결 방법 :

    • 계산의 용이성을 위해 plans 배열의 start(hh:mm)를 minutes로, playtime 부분을 정수로 변환 후 start를 기준으로 오름차순 정렬
    • plans를 돌며
      • 현재 시간 < 현재 과제의 시작 시간인 경우
        • 현재 시간이 현재 과제의 시작 시간이 될 때까지 stack에 저장된(잠시 멈춘) 과제를 수행
        • 이 때 현재 시간 + 가장 최근에 멈춘 과제의 남은 시간 <= 현재 과제의 시작 시간인 경우 answer에 push
        • 그 외의 경우 수행한 시간을 제외하고 가장 최근에 멈춘 과제의 남은 시간 stack에 update
      • 과제의 시작 시간 + 걸리는 시간 > 다음 과제의 시작 시간인 경우
        • 차이만큼 남은 시간 stack에 push
        • 다음 과제의 시작 시간으로 현재 시간 update
      • 과제의 시작 시간 + 걸리는 시간 <= 다음 과제의 시작 시간인 경우
        • answer에 push
        • 과제의 시작 시간 + 걸리는 시간으로 현재 시간 update
  • 회고 :

    • 처음에 작성한 코드

      const hhmmToMinutes = (hhmm) => {
        const [hh, mm] = hhmm.split(':').map((v) => +v);
      
        return hh * 60 + mm;
      };
      
      function solution(plans) {
        const answer = [];
        const stack = [];
      
        plans = plans
          .map((plan) => [plan[0], hhmmToMinutes(plan[1]), +plan[2]])
          .sort((a, b) => a[1] - b[1]);
      
        let time = plans[0][1];
      
        plans.forEach((plan, i) => {
          const [name, start, playtime] = plan;
      
          while (time < start) {
            if (stack.length === 0) {
              time = start;
              break;
            }
      
            const [n, pt] = stack.pop();
      
            if (time + pt < start) {
              time = start + pt;
            } else if (time + pt > start) {
              stack.push([n, pt + time - start]);
              time = start;
            } else {
              time = start;
              break;
            }
          }
      
          if (i === plans.length - 1) {
            answer.push(name);
            return;
          }
      
          if (start + playtime > plans[i + 1][1]) {
            stack.push([name, start + playtime - plans[i + 1][1]]);
            time = plans[i + 1][1];
          } else {
            answer.push(name);
            time = start + playtime;
          }
        });
      
        stack.reverse().forEach((v) => answer.push(v[0]));
      
        return answer;
      }
      
    • 대부분의 테스트 케이스에서 실패했다..

      image

    • 로직 중 잘못된 부분을 찾던 중 while문 속에 answer에 push하는 부분과 time 업데이트하는 부분을 잘못 작성했다..
    • 수정한 코드

      // while (time < start) {
      //   if (stack.length === 0) {
      //     time = start;
      //     break;
      //   }
      //
      //   const [n, pt] = stack.pop();
      //
      //   if (time + pt < start) {
      //     time = start + pt;
      //   } else if (time + pt > start) {
      //     stack.push([n, pt + time - start]);
      //     time = start;
      //   } else {
      //     time = start;
      //     break;
      //   }
      // }
      
      while (time < start) {
        if (stack.length === 0) {
          time = start;
          break;
        }
      
        const [n, pt] = stack.pop();
      
        if (time + pt <= start) {
          time += pt;
          answer.push(n);
        } else {
          stack.push([n, pt + time - start]);
          time = start;
        }
      }
      
    • 통과 ~~!!

      image

  • 코드

    const hhmmToMinutes = (hhmm) => {
      const [hh, mm] = hhmm.split(':').map((v) => +v);
    
      return hh * 60 + mm;
    };
    
    function solution(plans) {
      const answer = [];
      const stack = [];
    
      plans = plans
        .map((plan) => [plan[0], hhmmToMinutes(plan[1]), +plan[2]])
        .sort((a, b) => a[1] - b[1]);
    
      let time = plans[0][1];
    
      plans.forEach((plan, i) => {
        const [name, start, playtime] = plan;
    
        while (time < start) {
          if (stack.length === 0) {
            time = start;
            break;
          }
    
          const [n, pt] = stack.pop();
    
          if (time + pt <= start) {
            time += pt;
            answer.push(n);
          } else {
            stack.push([n, pt + time - start]);
            time = start;
          }
        }
    
        if (i === plans.length - 1) {
          answer.push(name);
          return;
        }
    
        if (start + playtime > plans[i + 1][1]) {
          stack.push([name, start + playtime - plans[i + 1][1]]);
          time = plans[i + 1][1];
        } else {
          answer.push(name);
          time = start + playtime;
        }
      });
    
      stack.reverse().forEach((v) => answer.push(v[0]));
    
      return answer;
    }
    
  • 출처: 프로그래머스 코딩 테스트 연습, https://school.programmers.co.kr/learn/challenges