문제 설명
주차장의 요금표와 차량이 들어오고(입차) 나간(출차) 기록이 주어졌을 때, 차량별로 주차 요금을 계산하려고 합니다. 아래는 하나의 예시를 나타냅니다.
요금
기본 시간(분) | 기본 요금(원) | 단위 시간(분) | 단위 요금(원) |
180 | 5000 | 10 | 600 |
시각(시:분) | 차량 번호 | 내역 |
05:34 | 5961 | 입차 |
06:00 | 0 | 입차 |
06:34 | 0 | 출차 |
07:59 | 5961 | 출차 |
07:59 | 148 | 입차 |
18:59 | 0 | 입차 |
19:09 | 148 | 출차 |
22:59 | 5961 | 입차 |
23:00 | 5961 | 출차 |
- 자동차별 주차 요금
차량 번호 | 누적 주차 시간(분) | 주차 요금(원) |
0 | 34 + 300 = 334 | 5000 + ⌈ (334 - 180) / 10⌉ x 600 = 14600 |
148 | 670 | 5000 + ⌈ (670 - 180) / 10⌉ x 600 = 34400 |
5961 | 145 + 1 = 146 | 5000 |
- 어떤 차량이 입차된 후에 출차된 내역이 없다면, 23:59에 출차된 것으로 간주합니다.
0000
번 차량은 18:59에 입차된 이후, 출차된 내역이 없습니다. 따라서, 23:59에 출차된 것으로 간주합니다.
- 00:00부터 23:59까지의 입/출차 내역을 바탕으로 차량별 누적 주차 시간을 계산하여 요금을 일괄로 정산합니다.
- 누적 주차 시간이
기본 시간
이하라면,기본 요금
을 청구합니다.
- 누적 주차 시간이
기본 시간
을 초과하면,기본 요금
에 더해서, 초과한 시간에 대해서단위 시간
마다단위 요금
을 청구합니다. - 초과한 시간이
단위 시간
으로 나누어 떨어지지 않으면,올림
합니다. ⌈
a⌉
: a보다 작지 않은 최소의 정수를 의미합니다. 즉,올림
을 의미합니다.
주차 요금을 나타내는 정수 배열
fees
, 자동차의 입/출차 내역을 나타내는 문자열 배열 records
가 매개변수로 주어집니다. 차량 번호가 작은 자동차부터 청구할 주차 요금을 차례대로 정수 배열에 담아서 return 하도록 solution 함수를 완성해주세요.제한사항
fees
의 길이 = 4- fees[0] =
기본 시간(분)
- 1 ≤ fees[0] ≤ 1,439
- fees[1] =
기본 요금(원)
- 0 ≤ fees[1] ≤ 100,000
- fees[2] =
단위 시간(분)
- 1 ≤ fees[2] ≤ 1,439
- fees[3] =
단위 요금(원)
- 1 ≤ fees[3] ≤ 10,000
- 1 ≤
records
의 길이 ≤ 1,000 records
의 각 원소는"시각 차량번호 내역"
형식의 문자열입니다.시각
,차량번호
,내역
은 하나의 공백으로 구분되어 있습니다.시각
은 차량이 입차되거나 출차된 시각을 나타내며,HH:MM
형식의 길이 5인 문자열입니다.HH:MM
은 00:00부터 23:59까지 주어집니다.- 잘못된 시각("25:22", "09:65" 등)은 입력으로 주어지지 않습니다.
차량번호
는 자동차를 구분하기 위한, `0'~'9'로 구성된 길이 4인 문자열입니다.내역
은 길이 2 또는 3인 문자열로,IN
또는OUT
입니다.IN
은 입차를,OUT
은 출차를 의미합니다.records
의 원소들은 시각을 기준으로 오름차순으로 정렬되어 주어집니다.records
는 하루 동안의 입/출차된 기록만 담고 있으며, 입차된 차량이 다음날 출차되는 경우는 입력으로 주어지지 않습니다.- 같은 시각에, 같은 차량번호의 내역이 2번 이상 나타내지 않습니다.
- 마지막 시각(23:59)에 입차되는 경우는 입력으로 주어지지 않습니다.
- 아래의 예를 포함하여, 잘못된 입력은 주어지지 않습니다.
- 주차장에 없는 차량이 출차되는 경우
- 주차장에 이미 있는 차량(차량번호가 같은 차량)이 다시 입차되는 경우
풀이
은찬
const solution = (fees, records) => { const answer = []; const [limitTime, feePerLimit, minute, feePerMinute] = fees; const inCars = new Map(); const outCars = new Map(); const carsNumber = []; for(const record of records){ const [time, number, state] = record.split(" "); carsNumber.push(number); if(state === "IN"){ inCars.set(number, time); } else{ const [inHour, inMinute] = inCars.get(number).split(":"); const [outHour, outMinute] = time.split(":"); const inTotal = (parseInt(inHour) * 60) + parseInt(inMinute); const outTotal = (parseInt(outHour) * 60) + parseInt(outMinute); const savedTime = outCars.get(number) || 0; outCars.set(number, savedTime + (outTotal - inTotal)); inCars.delete(number); } } for(const [key, value] of inCars){ const [inHour, inMinute] = value.split(":"); const savedTime = outCars.get(key) || 0; outCars.set(key, savedTime + ((60 * 23) + 59) - ((parseInt(inHour) * 60) + parseInt(inMinute))); } const orderedNumbers = [...new Set(carsNumber)].sort((a, b) => a - b); for(const number of orderedNumbers){ const totalTime = outCars.get(number); const totalFee = totalTime <= limitTime ? feePerLimit : (feePerLimit + (Math.ceil((totalTime - limitTime) / minute) * feePerMinute)); answer.push(totalFee); } return answer; }
재영
const getTime = (time) => { const [hour, minutes] = time.split(":"); return +hour * 60 + +minutes; } const calculateCost = (fees, inTime, outTime, totalTime) => { const [baseTime, baseCost, unitTime, unitCost] = fees; if (!inTime && !outTime) return totalTime > baseTime ? baseCost + Math.ceil((totalTime - baseTime) / unitTime) * unitCost : baseCost const timeDiff = getTime(outTime) - getTime(inTime); return ((timeDiff + totalTime >= baseTime) ? Math.ceil((timeDiff + totalTime - baseTime) / unitTime) * unitCost : 0 ) + baseCost } function solution(fees, records) { const infos = {}; const endTime = '23:59' records.forEach(record => { const [time, carNumber, status] = record.split(' '); const nextInfo = { time, status, total: 0, totalTime: 0 } if (!infos[carNumber]) { infos[carNumber] = nextInfo } else { const memo = { ...infos[carNumber] } infos[carNumber] = { time, status, total: 0, totalTime: memo.totalTime + (status === 'OUT' ? getTime(time) - getTime(memo.time) : 0) } } }) for (const carNumber in infos) { const info = infos[carNumber]; if (info.status === 'IN') { infos[carNumber] = { ...info, status: 'OUT', total: info.total + (info.status === 'IN' ? calculateCost(fees, info.time, endTime, infos[carNumber].totalTime) : 0) } } else { infos[carNumber] = { ...info, total: calculateCost(fees, null, null ,infos[carNumber].totalTime) } } } const answer = Object.entries(infos).sort((a, b) => a[0] - b[0]).map(([key, value]) => value.total) return answer; }
효성
function solution(fees, records) { const memo = new Map(); const totalFee = new Map(); records.forEach(el => { const splitEl = el.split(' '); const [time, carNum, history] = splitEl; if(history === 'IN') { memo.set(carNum, time); } else { const inTime = memo.get(carNum); memo.delete(carNum); const inTimeSplit = inTime.split(':'); const timeSplit = time.split(':'); const totalTime = calcTime(inTimeSplit, timeSplit); if(totalFee.has(carNum)) { const newTime = totalFee.get(carNum) + totalTime; totalFee.set(carNum, newTime); } else { totalFee.set(carNum, totalTime); } } }); const restArr = [...memo]; restArr.forEach(el => { const [carNum, time] = el; const timeSplit = time.split(':'); const hour = Number(timeSplit[0]), min = Number(timeSplit[1]); const lastHour = 23, lastMin = 59; const calcTime = (lastHour - hour) * 60 + (lastMin - min); if(totalFee.has(carNum)) { const newTime = totalFee.get(carNum) + calcTime; totalFee.set(carNum, newTime); } else { totalFee.set(carNum, calcTime); } }); const answer = []; const final = [...totalFee].sort((a, b) => a[0] - b[0]); final.forEach(el => { const totalTime = el[1]; if(totalTime <= fees[0]) { answer.push(fees[1]); } else { const fee = fees[1] + Math.ceil((totalTime - fees[0]) / fees[2]) * fees[3]; answer.push(fee); } }) return answer; } function calcTime(inTime, outTime) { let hourDiff = 0, minDiff = 0; const inHour = Number(inTime[0]), inMin = Number(inTime[1]); const outHour = Number(outTime[0]), outMin = Number(outTime[1]); if(inMin < outMin) { hourDiff = outHour - inHour; minDiff = Math.abs(inMin - outMin); return hourDiff * 60 + minDiff; } else { hourDiff = outHour - inHour - 1; minDiff = 60 - inMin + outMin; return hourDiff * 60 + minDiff; } }