프로그래머스 - [주차 요금 계산] - 해시 Lv.2

JH.P·2022년 8월 3일

해쉬 맵

  • 해쉬 맵을 이용하여 해결 가능한 문제였다.

풀이에 필요한 요소

  • 두 시간과의 차이를 계산하고 분 단위로 환산하기 위하여 Date 객체를 이용한다.

로직

  • 해쉬 맵을 이용하고, 해쉬 맵은 다음과 같은 구조를 따른다.
"자동차번호" : {누적 주차 시간, 입출차기록}
  • 자동차 번호 별로 입차한 시간을 기록하면서 출차하게 되면, 그 즉시 출차 시간과 입차 시간의 차이를 계산하여 누적 주차 시간에 합한다.
  • 만약 출차 기록이 존재하지 않으면 23:59에 출차한 것으로 간주하여, 23:59과 마지막 입차 시간을 계산하여 누적 주차 시간에 합한다.
  • 자동차 별로 모든 누적 주차 시간이 계산된다면, 정답은 자동차 번호의 오름차순 정렬 순서대로 반환해야하기 때문에 자동차 번호를 기준으로 오름차순으로 정렬한다.
  • 제시된 공식을 이용하여 자동차 별로 주차 요금을 산정한다.

코드

function solution(fees, records) {
    // 모든 차의 주차 요금 산정은 '기본 요금' + ('누적 주차 시간(분) - 기본시간(분)') / 단위시간 * 단위 요금
    // 만약 누적 주차 요금이 기본 시간 이하라면, 기본 요금 청구
    // < 차량 입출차 기록 >
    // records를 순회 => 차량을 key로 입차, 출차 체크
    // records의 요소가 입차 하고, 출차 했으면,  출차 시간과 입차 시간의 차이를 value
    // 만약 다시 입차한 경우, 출차도 체크, 만약 출차 기록이 없으면 23:59에 출차한 것으로 체크
    
    // 차량 별 누적 주차 시간(분) 해쉬맵으로 저장
    const inOutMap = new Map()
    records = records.map(el => el.split(' '))
    records.forEach((item, idx) => {
        // var start = new Date('2020-10-14 09:00:00');
        // 해쉬의 형태 : "자동차번호" : {누적 주차 시간, 입출차기록}
        const data = inOutMap.get(item[1]) || {time: 0, inOut: ''}
        if(item[2] === 'IN') {  
            // 입차했음을 알림
            inOutMap.set(item[1], {time: data.time, inOut: new Date(`2020-10-14 ${item[0]}:00`)})
        } else {    
            // 출차된 시간 - 입차된 시간 계산
            const diffTime = (new Date(`2020-10-14 ${item[0]}:00`).getTime() - data.inOut.getTime()) / (1000 * 60)
            // 계산된 시간을 누적 주차 시간에 더하기
            inOutMap.set(item[1], {time: data.time + diffTime, inOut: ''})
        }
    })
   
    let inOutArr = [...inOutMap]
    for(let i = 0; i < inOutArr.length; i++) {
        if(inOutArr[i][1].inOut !== '') {
            // 23:59와 마지막 입차시간의 차이 
            const diffTime = (new Date('2020-10-14 23:59:00').getTime() - inOutArr[i][1].inOut.getTime()) / (1000 * 60)
            inOutArr[i][1]['time'] = inOutArr[i][1]['time'] + diffTime
        }
    }
    inOutArr.sort((a, b) => Number(a[0]) - Number(b[0]))
    // 최종 주차 요금 계산
    const answer = []
    inOutArr.forEach((el, idx) => {
        const time = el[1].time
        if(time <= fees[0]) {
            answer.push(fees[1])
        } else {
            answer.push(fees[1] + Math.ceil((time - fees[0]) / fees[2]) * fees[3])
        }
    })
    return answer
}

문제 조건 파악에 헷갈렸던 사항

  • 차량 별로 입 출차를 2번 이상 할 경우도 존재한다. 이때 입 출차 각각의 경우를 요금을 따로 계산해서 최종적으로 합산해야 하는 것인지 의문이 들었었다.
    ex) 기본 제공 시간이 120분이고, 기본 요금이 0원이면, 입 출차를 2시간씩 2번씩 하면 내는 돈은 0원인건가..?
  • 입출력 예시 2번을 보니, 여러 차례 입출차들이 모두 기본 제공 시간 내에 이루어져도, 시간을 일괄적으로 합산하여 요금이 계산되는 것을 보고 다시 한 번 조건을 확인하였다.
00:00부터 23:59까지의 입/출차 내역을 바탕으로 차량별 누적 주차 시간을 계산하여 요금을 일괄로 정산합니다.

위 조건을 다시 한 번 확인하고 문제 조건을 명확하게 이해했다. 즉, 기본 요금이 0원이라고 가정하면, 여러 번 기본 제공 시간 내에 출차되더라도 내는 요금은 0원이 아니라 그 날 하루 동안의 누적 주차 시간을 바탕으로 계산된다.

profile
꾸준한 기록

0개의 댓글