sooleeandtomas

[day28] 코딩테스트 알고리즘 - 주차 요금 계산 (feat.파이썬) 본문

코딩테스트 알고리즘/기타

[day28] 코딩테스트 알고리즘 - 주차 요금 계산 (feat.파이썬)

sooleeandtomas 2022. 12. 1. 23:18

👧🏻 문제 포인트

✅ 데이터 체크

기본 시간 이하인가 기본 요금 청구

ex) 11:30 입차 11:40 출차인 경우
주차시간이 10분 이기때문에

주차시간 <= 기본시간:
 + 기본요금
기본 시간을 초과했는가 기본 요금 + 초과한 시간에 단위 시간마다 단위 요금을 청구

n분당 p원으로 계산해야함.
Math.ceil(총분 / n) 올림 (문제 참고 초과한 시간이 단위 시간으로 나누어 떨어지지 않으면, 올림 합니다)

ex) 11:30분 입차 . 12:20분 출차한경우
총 50분 주차했으니 기본시간 초과이다.  (주차시간 > 기본시간)

최종 주차시간을 b라 하자.
b = 총주차시간 - 기본시간
총 요금 = 기본요금 + Math.ceil(b / n)

 

✅ 데이터 가공

시각 HH:MM 길이 5인 문자열이 주어짐

입차시각과 출차시각이 총 몇 분인지를 계산해야함
(출차H*60 + 출차M) - (입차H*60 + 입차M)
ex) 11:30 입차 12:20 출차
12*60 + 20 = 740
11*60 + 30 = 690
740 - 690 = 50
차량 번호 4길이의 숫자로 이루어짐. 
최종 답안은 차량 번호를 정렬해서 반환
내역 IN / OUT 
IN 은 입차 
OUT은 출차로 고려해서 데이터를 나눠줘야함.

어떤 형태의 데이터가 이 문제를 풀기에 가장 적합할까요?

- 주어진 형태 : [ "05:34 5961 IN", "06:00 0000 IN", "06:34 0000 OUT",....]

- 정리 형태 : { carNum : time(int), carNum: time(int).... }

- 최종적으로 차량번호로 정렬을 해야하기 때문에 배열이 되어야 함[]

- 최종적으로 차량번호와 주차요금이 담긴 객체를 가져야 함 {차량번호, 주차요금}

 

 

✅ 추가 고려사항

입차가 된 후 출차가 되지
않은 경우
출차가 23:59에 되었다고 판단해야함.
ex) 11:30에 입차 후 출차된 기록이 없는 경우 
위의 시각 구하는 것을 참고하여
11*60 + 30 = 690
23*60 + 59  = 1439
1439 - 690 = 749

 

👧🏻 참고 코드

from collections import defaultdict
from math import ceil


def getTime(time):
    h, m = time.split(":")
    return int(h) * 60 + int(m)


def calcFee(time, baseTime, baseFee, unitTime, unitFee):
    extraTime = max(0, time - baseTime)
    extraFee = baseFee + ceil(extraTime / unitTime) * unitFee
    return extraFee


def solution(fees, records):
    answer = []

    baseTime, baseFee, unitTime, unitFee = fees

    parkRecord = defaultdict(int)
    parkLot = dict()

    for record in records:
        time, carNum, type = record.split(" ")
        time = getTime(time)
        if type == "IN":
            parkLot[carNum] = time
        else:
            parkRecord[carNum] += time - parkLot[carNum]
            del parkLot[carNum]

    for carNum in parkLot:
        parkRecord[carNum] += getTime("23:59") - parkLot[carNum]

    for carNum in parkRecord:
        parkFee = calcFee(parkRecord[carNum], baseTime, baseFee, unitTime, unitFee)
        answer.append([carNum, parkFee])
    answer.sort()
    answer = [x[1] for x in answer]
    return answer

출처 : jahni's blog

 

👧🏻  파이썬 문법 defaultdict를 사용하는 이유

dictionary로 자료를 관리하려 할 때 디폴트 값이 없으면 0으로 처리를 해줘야 한다.

이때 if letter not in counter : ~~ 이러한 처리는 가독성을 해친다.

cars = [5000, 6000, 2000]

def setPark(cars):
    parklot = {}
    for car in cars:
        if car not in parklot:
            parklot[car] = 0
        parklot[car] += 1
    return parklot
    
#parklot = { 5000:1, 6000:1, 2000:1}

 

dict.setdefault

이를 보완하기 위한 방법으로는 dict.setdefault(letter, 0) 이 있다.

cars = [5000, 6000, 2000]

def setPark(cars):
    parklot = {}
    for car in cars:
        parklot.setdefault(car, 0)
        parklot[car] += 1
    return parklot
    
#parklot = { 5000:1, 6000:1, 2000:1}

 

collections.defaultdict

이때 파이써닉한 코드를 사용해볼 수 있다. 파이썬의 내장 모듈인 collections의 defaultdict를 사용하면 

알아서 기본 초기값을 셋팅해준다.

from collections import defaultdict

cars = [5000, 6000, 2000]

def setPark(cars):
    parklot = defaultdict(int)
    for car in cars:
        parklot[car] += 1
    return parklot
    
#parklot = { 5000:1, 6000:1, 2000:1}

 

defaultdict에서 int 말고도 lamba:0, list를 넣을 수 있다.

 

출처 : https://www.daleseo.com/python-collections-defaultdict/

 

Comments