프로그래머스 LEVEL 3(셔틀버스)

image

  • 사용 언어 : javascript

  • 해결 날짜 : 2023-01-24

  • 해결 방법 :

    • 가짓수가 최대 10 * 2000(n * timetable)이기 때문에 단순 반복문으로 문제 해결
    • hhmm 형식의 시간을 쉽게 계산하기 위해 hhmm을 분으로 변환하는 함수와(hhmmToMinutes) 분을 hhmm으로 변환하는 함수(minutesToHhmm) 사전 정의
    • timetable을 분으로 변환 후 오름차순 정렬
    • 콘은 최대한 늦게 도착해야 하기 때문에 먼저 마지막 셔틀 버스 운행 전까지 탑승 가능한 크루를 구함
      • 한 셔틀 당 최대 m명까지 탑승 가능하므로
        • 현재 셔틀의 시간보다 작거나 같은 시간에 도착한 크루의 길이와 m 중 최소값 만큼 대기줄에서 제거
      • 한 번 셔틀 태울 때 마다 셔틀의 시간 t만큼 증가
    • 콘이 마지막 셔틀 버스를 탑승하기 위해
      • 남은 대기줄에서 마지막 셔틀의 시간보다 작거나 같은 크루들의 길이가 m보다 작다면
        • 콘은 마지막 셔틀의 도착 시간에 도착해도 탑승 가능(shuttle)
      • 크다면 candidates에 들어가야 하고, 대기열에서 가장 뒤에 서야하므로
        • m명까지 탑승할 수 있는 선에서 가장 늦게 온 크루보다 1분만 빨리오면 탑승 가능(candidates[m - 1] - 1)
  • 회고 :

    • hh:mm 형식의 시간을 Date 객체로 변환 후 계산하거나 직접 string 값을 변화시키는 것 보다 계산하기 편한 minutes로 바꾸기
  • 코드

    function solution(n, t, m, timetable) {
      const hhmmToMinutes = (hhmm) => {
        const [hh, mm] = hhmm.split(':');
        return parseInt(hh, 10) * 60 + parseInt(mm, 10);
      };
    
      const minutesToHhmm = (minutes) => {
        const hh = Math.floor(minutes / 60)
            .toString()
            .padStart(2, '0'),
          mm = (minutes % 60).toString().padStart(2, '0');
        return `${hh}:${mm}`;
      };
    
      let shuttle = hhmmToMinutes('09:00');
      let line = timetable.map((hhmm) => hhmmToMinutes(hhmm)).sort((a, b) => a - b);
    
      for (let i = 0; i < n - 1; i++) {
        const candidateCount = line.filter((e) => e <= shuttle).length;
        const passengerCount = Math.min(candidateCount, m);
    
        shuttle += t;
        line = line.slice(passengerCount);
      }
    
      const candidates = line.filter((e) => e <= shuttle);
    
      return minutesToHhmm(candidates.length < m ? shuttle : candidates[m - 1] - 1);
    }
    
  • 출처: 프로그래머스 코딩 테스트 연습, https://school.programmers.co.kr/learn/challenges