Algorithm/Coding Test
(2022 KAKAO BLIND RECRUITMENT) 주차 요금 계산
Bumang
2023. 7. 19. 00:46
https://school.programmers.co.kr/learn/courses/30/lessons/92341
문제 수준:
레벨2
문제 요약:
자동차 요금 계산을 하는 문제.
1. 기본 시간 이내에 나갈 시 기본 요금만 부과.
2. 기본 시간을 초과할 시 n분 당 m원 부과.
3. 나갈 때 계산하는게 아니라 하루의 끝에 총 시간을 정산하는 방식
4. 하루가 지나도록 안 나가면(00:00분이 지나면), 23:59에 출차한 것으로 정산.
입출력 예 (입력 / 출력):
fee[0]은 기본 시간, fee[1]은 기본 요금, fee[2]는 단위 시간, fee[3]은 단위 요금
records는 "시간 차번호 입차/출차" 꼴로 되어 있다.
번호판 숫자가 작은 것부터 요금을 배열로 정리해서 내야한다.
문제 풀이 전략:
들어온 시간 객체(inSpan)와 나간 시간 객체(outSpan)를 생성하여 활용한다.
그리고 차 번호를 고유값 key로 사용하여 (나간 시간 - 들어온 시간)을 하여
총 시간 기록용 객체(totalMinSum)에 기록한다.
마지막에 총 시간 기록용 객체에 있는 데이터를 기반으로 차 별 총 시간을 규칙에 맞추어 요금 정산한다.
내 풀이:
function solution(fees, records) {
const [stdMinTime, stdFee, perMinTime, perFee] = fees
const inSpan = {} // 입차 시간 객체
const outSpan = {} // 출차 시간 객체
const totalMinSum = {} // 총 시간 기록 객체
const totalFee = {} // 총 요금 정리
const result = [] // 채점 반환용 배열
for (spec of records) { /* (입출차 시간 파악해서) 차 별로 머문 시간 계산하는 파트 */
const recList = spec.split(" ") // 공백으로 나눠서
const [recHourTime, recCarID, recWard] = recList // 시 단위 시간, 차번호, 방향을 변수로 얻음
const recMinTime = convertMinute(recHourTime) // 시 단위 시간을 분 단위 시간으로 변환
if (recWard === "IN") { // 만약 "입차"라면...
inSpan[recCarID] = recMinTime // 입차 시간 객체에 기록
} else { // 출차라면
outSpan[recCarID] = recMinTime // 출차 시간 객체에 기록
calculateTimeSpan(recCarID) // 몇 분 동안 주차했는지 계산하는 함수 호출 (출차 시간 - 입차 시간).
// 몇 분 동안 주차했는지 계산하여 총 시간 객체(totalMinSum)에 기록한다.
inSpan[recCarID] = null // 입차 기록 초기화
outSpan[recCarID] = null // 출차 기록 초기화
}
}
for (recCarID in inSpan) { /* 나가지 않은 차들 정산하는 파트*/
if (inSpan[recCarID] !== null) { // 초기화 되지 않은 입차기록이 있다면
outSpan[recCarID] = convertMinute("23:59") // 나가지 않고 하루 지난 것이므로 23:59로 정산...
calculateTimeSpan(recCarID) // 다시 요금 구하기
inSpan[recCarID] = null // 비로소 입차 시간 초기화
outSpan[recCarID] = null // 비로소 출차 시간 초기화
}
}
for (recCarID in inSpan) { // 요금 정산하는 파트
if (totalMinSum[recCarID] <= stdMinTime) { // 기준 시간보다 총 시간이 짧거나 같다면
totalFee[recCarID] = stdFee // 기본 요금만 내쇼!
} else { // 기준 시간을 초과한다면
totalFee[recCarID] = stdFee + perFee
* Math.ceil((totalMinSum[recCarID] - stdMinTime) / perMinTime)
// 기본 요금 + 단위 요금 * ((총 시간 - 기본 시간) / 단위 시간)의 반올림 만 내쇼!
}
}
const IDOrder = Object.keys(totalFee).sort((a,b)=> a - b) //번호 작은 순서로 차 번호 정렬
for (let i = 0; i < IDOrder.length; i++) {
result.push(totalFee[IDOrder[i]]) //번호 작은 순서대로 요금 정산했던거 result에 넣기
}
return result // 답 제출!!
function calculateTimeSpan(recCarID) { /* 몇 분 있었는지 정산하는 함수 */
const subMinTime = outSpan[recCarID] - inSpan[recCarID]
totalMinSum[recCarID] = (totalMinSum[recCarID] || 0) + subMinTime
}
function convertMinute(time) { /* 분 단위로 변환하는 함수 */
const temp = time.split(":")
let [hour, min] = temp
return Number(hour) * 60 + Number(min)
}
}