주차 요금 계산은 주어진 요금표와 차량 기록을 계산하여 차 번호 순으로 요금을 반환하는 문제이다. 어려운 알고리즘은 없지만 분 단위로 치환한 후 각 차량번호에 매핑한 후 사용시간을 합산하여 기본요금 혹은 기본요금에 추가요금을 합산한 값을 구하는 과정과 출차 기록이 없을 경우 23:59분을 기준으로 요금을 더해줘야 하는 예외 처리로 인해 난이도가 올라가는 문제이다.
처음 문제를 읽고 접근할 때 키(차량번호)와 값(사용시간)을 구하는 것이 문제 풀이의 핵심이라고 생각했다.
Set과 Map을 그 동안 몇 번 사용해봤기 때문에 개념은 어렴풋이 알고 있었지만 이런 키와 쌍의 값을 저장하고 중복을 방지하기에는 Map이 적절한 자료구조라는 부분을 다시 깨닫았다.
또한 string 형태로 주어지는 배열을 분해 후 형변환하여 시간과 요금을 계산하는 과정은 오탈자나 연산 처리에 실수가 있으면 아예 다른 값이 나와 오류 핸들링이 어려워서 까다롭게 작성했다.
00:00시에 입차한 후 출차 기록이 없는 경우에 대해서 예외처리를 하지 않았다.
function solution(fees, records) {
const parking = new Map();
const [bTime, bFee, uTime, uFee] = fees;
for (let i = 0; i < records.length; i++) {
let [time, car, status] = records[i].split(" "),
[hour, minute] = time.split(":");
time = 60 * Number(hour) + Number(minute);
if (status === "IN") {
parking.set(car, {
total: parking.has(car) ? parking.get(car).total : 0,
time,
});
} else if (status === "OUT") {
const parkTime = parking.get(car);
const spandTime = time - parkTime.time;
parkTime.total += spandTime;
parkTime.time = 0;
parking.set(car, parkTime);
}
}
for (let [car, parkTime] of parking) {
let { total, time } = parkTime;
if (time > 0) {
total += 23 * 60 + 59 - time;
parking.set(car, { total, time: 0 });
}
}
return [...parking]
.sort((a, b) => a[0] - b[0])
.map(([_, { total, time }]) =>
total <= bTime ? bFee : bFee + Math.ceil((total - bTime) / uTime) * uFee
);
}
function solution(fees, records) {
const parking = new Map();
const [bTime, bFee, uTime, uFee] = fees;
for (let i = 0; i < records.length; i++) {
let [time, car, status] = records[i].split(" "),
[hour, minute] = time.split(":");
time = 60 * Number(hour) + Number(minute);
if (status === "IN") {
parking.set(car, {
total: parking.has(car) ? parking.get(car).total : 0,
time,
});
} else if (status === "OUT") {
const parkTime = parking.get(car);
const spandTime = time - parkTime.time;
parkTime.total += spandTime;
parkTime.time = 0;
parking.set(car, parkTime);
}
}
for (let [car, parkTime] of parking) {
let { total, time } = parkTime;
// 첫 입차 후 출차하지 않았거나 차량의 마지막 기록 이후 출차하지 않은 경우
if (time > 0 || total <= 0) {
total += 23 * 60 + 59 - time;
}
// 모든 차량의 입출차 처리 후 가격 계산 - 기본요금 혹은 추가요금 + 기본요금
const fee =
total <= bTime ? bFee : bFee + Math.ceil((total - bTime) / uTime) * uFee;
// 저장된 시간 객체를 전체요금으로 형변환 후 값으로 재할당
parking.set(car, fee);
}
return [...parking].sort((a, b) => a[0] - b[0]).map((e) => e[1]);
}
잘푸셨네요!