본문 바로가기
코테연습

160. 주차 요금 계산 Javascript

by hxunz 2022. 9. 19.

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

 

프로그래머스

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

programmers.co.kr

 

1. 문제에 대한 이해

  • 우리가 풀어야 할 문제는 무엇인가?
     - 차량 번호가 작은 자동차부터 청구할 주차 요금을 차례대로 정수 배열에 담아서 return
  • 주어진 자료는 무엇인가?
     - 주차 요금을 나타내는 정수 배열 fees
     - 자동차의 입/출차 내역을 나타내는 문자열 배열 records
     - records의 각 원소는 "시각 차량번호 내역" 형식의 문자열
     - 시각은 차량이 입차되거나 출차된 시각을 나타내며, HH:MM 형식의 길이 5인 문자열
     - 차량번호는 자동차를 구분하기 위한, `0'~'9'로 구성된 길이 4인 문자열
     - 내역은 길이 2 또는 3인 문자열로, IN 또는 OUT입니다. IN은 입차를, OUT은 출차
  • 조건은 무엇인가?
     - 어떤 차량이 입차된 후에 출차된 내역이 없다면, 23:59에 출차된 것으로 간주
     - 00:00부터 23:59까지의 입/출차 내역을 바탕으로 차량별 누적 주차 시간을 계산하여 요금을 일괄로 정산
     - 누적 주차 시간이 기본 시간이하라면, 기본 요금을 청구
     - 누적 주차 시간이 기본 시간을 초과하면, 기본 요금에 더해서, 초과한 시간에 대해서 단위 시간 마다 단위 요금을 청구
     - 초과한 시간이 단위 시간으로 나누어 떨어지지 않으면, 올림
     - ⌈a⌉ : a보다 작지 않은 최소의 정수를 의미합니다. 즉, 올림을 의미

2. 계획

  1. 각 차량의 누적 시간을 구한다. 
    1-1 Out에서 In 시간을 뺀다.
    1-2 출차 기록이 없다면 out을 23:59라고 설정
  2. 각 차량의 주차 요금을 구한다. 
    2-1 5000 + Math.ceil((누적시간 -1 80)/10) * 600
    2-2 누적 시간이 180을 넘지 않는다면 주차요금은 5000원
  3. 차량 번호가 작은 순으로 주차요금을 배열에 담아서 리턴한다. 

3. 실행

  • 풀이 계획을 실행하고, 각 단계가 올바른지 점검하라.
const solution = (fees, records) => {
  //   각 차량의 누적 시간을 구한다. 
  // 1 - 1 Out에서 In 시간을 뺀다.
  // 1 - 2 출차 기록이 없다면 out을 23: 59라고 설정

  // 각 차량의 주차 요금을 구한다.
  // 2 - 1 5000 + Math.ceil((누적시간 - 1 80) / 10) * 600
  //   2 - 2 누적 시간이 180을 넘지 않는다면 주차요금은 5000원
  // 차량 번호가 작은 순으로 주차요금을 배열에 담아서 리턴한다.

  const numbers = records.map((it) => it.split(' ')).map((num) => num[1]);
  const set = new Set(numbers);
  const carNumber = [...set].sort((a, b) => a - b);
  const totalParkingTime = Array.from({ length: carNumber.length }, (v, i) => 0);
  const parkingTime = records.map((it) => it.split(' ')).map((time) => [...time[0].split(':'), time[1], time[2]]);

  for (i = 0; i < carNumber.length; i++) {
    let count = 0;
    for (j = 0; j < parkingTime.length; j++) {
      if (carNumber[i] === parkingTime[j][2]) {
        count += 1;
        if (parkingTime[j][3] === 'IN') {
          totalParkingTime[i] -= (Number(parkingTime[j][0]) * 60) + Number(parkingTime[j][1])
        } else if (parkingTime[j][3] === 'OUT') {
          totalParkingTime[i] += (Number(parkingTime[j][0] * 60)) + Number(parkingTime[j][1])
        }
      }
    }
    if (count % 2 === 1) {
      totalParkingTime[i] += 1439
    }
  };

  const result = totalParkingTime.map((it) => {
    if (it > fees[0]) {
      return fees[1] + Math.ceil((it - fees[0]) / fees[2]) * fees[3]
    } else {
      return fees[1]
    }
  });

  return result;
};


test('parkingFee', () => {
  expect(solution([180, 5000, 10, 600], ["05:34 5961 IN", "06:00 0000 IN", "06:34 0000 OUT", "07:59 5961 OUT", "07:59 0148 IN", "18:59 0000 IN", "19:09 0148 OUT", "22:59 5961 IN", "23:00 5961 OUT"])).toEqual([14600, 34400, 5000]);
  expect(solution([120, 0, 60, 591], ["16:00 3961 IN", "16:00 0202 IN", "18:00 3961 OUT", "18:00 0202 OUT", "23:58 3961 IN"])).toEqual([0, 591]);
});

'코테연습' 카테고리의 다른 글

162. 행렬의 곱셈 Javascript  (0) 2022.09.19
161. 파괴되지 않은 건물 Javascript  (0) 2022.09.19
159. 캐시 Javascript  (0) 2022.09.19
158. 점프와 순간 이동 Javascript  (0) 2022.09.18
157. 예상 대진표 Javascript  (0) 2022.09.18

댓글