2024년 4월 22일 월요일

2022 KAKAO BLIND RECRUITMENT 주차 요금 계산 Lv. 2

문제 링크: https://school.programmers.co.kr/learn/courses/30/lessons/92341

파이썬 소스: https://bit.ly/4aUI7dU

 

 문제에서 요구한대로, 차근 차근 구현하면 풀 수 있는 문제입니다.

우선 시:분으로 입력받은 값을 분으로 변환하는 함수부터 코딩해보겠습니다.

def HH_MM(v: str):
    hh, mm = v.split(
':')
   
return int(hh) * 60 + int(mm)

‘:’콜론을 기준으로 시, 분을 나눠서, 시에만 60분을 곱하고, 둘을 더해줍니다.

 

문제를 풀기 위해서, 딕셔너리 2개를 사용하겠습니다.

dict_duration = defaultdict(int)
dict_records = defaultdict(
int)

두개의 딕셔너리 모두 키로 값으로 차량 번호를 사용합니다.

dict_duration은 해당 차량번호의 누적 주차시간을 분단위로 가지고 있습니다.

dict_records는 해당 차량번호의 마지막 입차시간을 분 단위로 가지고 있습니다.

for record in records:
    hh_mm, license_plate, _ = record.split(
' ')
   
if license_plate in dict_records.keys():
        dict_duration[license_plate] += HH_MM(hh_mm) - dict_records[license_plate]
       
del dict_records[license_plate]
   
else:
        dict_records[license_plate] = HH_MM(hh_mm)

/출차 내역 records를 하나씩 for 루프로 확인합니다.

차량 번호(license_plate) dict_records에 있으면, 입차 되어 있는 차가 출차 하는 기록 임으로, 주차한 시간을 계산해서 dict_duration에 더해 줍니다. 차량이 출차 했으므로, dict_records에서 해당 차량 번호를 삭제합니다.

 차량 번호(license_plate) dict_records에 없으면, 입차한 시간임으로, 해당 시간을 분으로 변환해서 dict_records에 저장합니다.

 

dict_record에 차량이 남아 있을 수 있습니다. 입차만 하고 출차하지 않은 경우입니다.

for license_plate in list(dict_records.keys()):
    dict_duration[license_plate] += HH_MM(
'23:59') - dict_records[license_plate]
   
del dict_records[license_plate]

주차 요금을 계산하기 전에 아직 출차 하지 않은 차가 있다면, 출차 시간을 ’23:59’으로 보고, 주차시간을 업데이트 해줍니다.

 모든 차량의 주차시간을 알게 되었으므로, 주차 요금을 계산해 보겠습니다.

def get_fee(fees, duration):
   
if duration <= fees[0]:
       
return fees[1]

    fee = fees[
1]
    duration -= fees[
0]
    q, r =
divmod(duration, fees[2])
    fee += q * fees[
3]
   
if r > 0:
        fee += fees[
3]

   
return fee

기본 시간(fees[0])보다 주차 시간이 작다면, 기본요금(fees[1])이 주차 요금 입니다.

기본 시간 보다 더 주차했으면, 주차시간에서 기본시간을 빼고, 남은 주차 시간에 해당하는 요금만 계산합니다.

이 때, 단위시간(fees[2])으로 나누어 떨어지지 않으면, 올림해서 주차 요금을 청구합니다. 따라서, ‘주차시간 / 단위시간의 몫과 나머지를 동시에 구할 수 있으면 코드량을 좀 줄일 수 있습니다.

divmod()함수를 사용해서 몫과 나머지를 동시에 구합니다. (q) 곱하기 단위요금을 주차요금에 더해주고, 나머지가 0보다 크다면, 즉 나머지가 있으면, 단위요금을 한번더 주차요금에 과금합니다.

 

주차시간에 따라서, 주차요금을 게산하는 for 루프입니다.

answer = []
for license_plate in list(dict_duration.keys()):
    fee = get_fee(fees, dict_duration[license_plate])
    answer.append([license_plate, fee])

딕셔너리 dict_duration에는 각 차량 번호의 누적 주차시간이 저장되어 있습니다. 주차시간에 따라서 주차요금을 계산하고, 차량번호와 주차요금을 answer에 추가합니다. 차량번호가 작은 자동차부터 청구할 주차 요금을 차례로 배열함으로, 차량 번호도 함께 answer에 추가합니다.

answer.sort(key=lambda item: item[0])

차량번호의 오름차순으로 리스트 answer를 정렬합니다.

return list(map(lambda item: item[1], answer))

리스트 answer에 들어 있는 차량번호는 제외하고, 주차 요금만 리스트에 담아서, 리턴하면 문제의 답을 구할 수 있습니다.

 

궁금한 내용은 댓글, 이메일(coding.data.pul@gmail.com)로 보내주세요.

코데풀 유튜브 구독 부탁드립니다.

https://www.youtube.com/@codapul

 

전체 코드는 아래에 있습니다.

from typing import List
from collections import defaultdict


def solution(fees: List[int], records: List[str]):
    dict_duration = defaultdict(
int)
    dict_records = defaultdict(
int)

   
for record in records:
        hh_mm, license_plate, _ = record.split(
' ')
       
if license_plate in dict_records.keys():
            dict_duration[license_plate] += HH_MM(hh_mm) - dict_records[license_plate]
           
del dict_records[license_plate]
       
else:
            dict_records[license_plate] = HH_MM(hh_mm)

   
for license_plate in list(dict_records.keys()):
        dict_duration[license_plate] += HH_MM(
'23:59') - dict_records[license_plate]
       
del dict_records[license_plate]

    answer = []
   
for license_plate in list(dict_duration.keys()):
        fee = get_fee(fees, dict_duration[license_plate])
        answer.append([license_plate, fee])

    answer.sort(
key=lambda item: item[0])
   
return list(map(lambda item: item[1], answer))


def get_fee(fees, duration):
   
if duration <= fees[0]:
       
return fees[1]

    fee = fees[
1]
    duration -= fees[
0]
    q, r =
divmod(duration, fees[2])
    fee += q * fees[
3]
   
if r > 0:
        fee += fees[
3]

   
return fee


def HH_MM(v: str):
    hh, mm = v.split(
':')
   
return int(hh) * 60 + int(mm)

 

댓글 없음:

댓글 쓰기