문제 이미지가 너무 많아서 생략했고, 원문은 프로그래머스 링크로 확인 가능하다.
문제 출처: https://school.programmers.co.kr/learn/courses/30/lessons/92341
난이도: Level 2
주차장의 요금표 fees와 차량의 입·출차 기록 records가 주어질 때, 차량별 주차 요금을 계산하는 문제다.
fees = [기본시간, 기본요금, 단위시간, 단위요금]records는 "시각 차량번호 IN/OUT" 형태로 주어진다.핵심은 “주차 중인 차량”과 “누적 주차 시간”을 분리해서 관리하는 것.
in_time: 현재 주차 중인 차량번호 → 입차 시각(분)
IN이면 저장OUT이면 (출차 - 입차)를 누적에 더하고 in_time에서 제거 del로 제거하면 in_time에는 “아직 출차 안 한 차량”만 남는다.total_time: 차량번호 → 누적 주차 시간(분)
+=로 계속 더해지므로 기본값 0이 편해서 defaultdict(int) 사용처리가 끝난 뒤 in_time에 남아있는 차량은 출차가 없는 케이스이므로
23:59 - 입차시각을 누적해 마감 처리한다.
마지막으로 차량번호를 오름차순 정렬하고,
ceil(초과시간 / 단위시간) * 단위요금을 더해 요금을 계산한다.from collections import defaultdict
import math
def to_total_m(str_time):
h, m = map(int, str_time.split(":"))
return 60 * h + m
def solution(fees, records):
in_time = {}
total_time = defaultdict(int)
for record in records:
time, number, cmd = record.split()
total_m = to_total_m(time)
if cmd == "IN":
in_time[number] = total_m
else:
total_time[number] += total_m - in_time[number]
del in_time[number] # 출차 처리 → 주차중 목록에서 제거
# 출차 기록 없는 차량은 23:59 출차로 처리
end = to_total_m("23:59")
for number in in_time.keys():
total_time[number] += end - in_time[number]
# 차량번호 오름차순으로 요금 계산
base_t, base_fee, unit_t, unit_fee = fees
result = []
for number in sorted(total_time.keys()):
t = total_time[number]
fee = base_fee
if t > base_t:
fee += math.ceil((t - base_t) / unit_t) * unit_fee
result.append(fee)
return result
처음에는 딕셔너리를 난사해서 자료구조가 꼬였고, 그 순간부터 디버깅 비용이 급격히 커졌다.
이런 “차근차근 구현” 문제는,
코드를 바로 치기 전에 말로 구조(자료구조 2개 + 처리 흐름)를 먼저 확정하는 게
겉으로는 느려 보여도 결국 가장 빠른 길이었다.
다시 풀어본 코드
from collections import defaultdict
import math
# fees = [180,5000,10,600]
# records = ["05:34 5961 IN", "06:00 0000 IN", "06:34 0000 OUT", "07:59 5961 OUT", "07:59 0148 IN", "18:59 0000 IN", "19:09 0148 OUT", "22:59 5961 IN", "23:00 5961 OUT"]
# "05:34" -> int(334) 로 만들어주는 함수
def to_min(time):
h, r = map(int,time.split(":"))
return 60 * h + r
def solution(fees,records):
entry = {} # 입차 시간
accumulated = defaultdict(int) # 누적 시간, 키 없을 경우 대비 defaultdict
# records cmd가 "IN" 이면
# entry[차량번호] = 입차 시간(분으로 환산)
for record in records:
time, number, cmd = record.split()
min_time = to_min(time)
if cmd == "IN":
entry[number] = min_time
elif cmd == "OUT":
parking_time = min_time - entry[number]
accumulated[number] += parking_time
del entry[number]
# records 다 돌았는데 entry[number] 에 차가 있다면 , "23:59" OUT 처리
for number in entry.keys():
parking_time = to_min("23:59") - entry[number]
accumulated[number] += parking_time
# accumulated = {"5961":146,"0000":334,"0148":670}
# 차 번호 오름차순 정렬
car_number = []
for number in accumulated.keys():
car_number.append(number)
car_number.sort()
# [0000","0148","5961]
# 주차 요금 계산
# fees = [180,5000,10,600]
result = []
for number in car_number:
if accumulated[number] > fees[0]:
fee = fees[1] + math.ceil((accumulated[number] - fees[0]) / fees[2]) * fees[3]
else:
fee = fees[1]
result.append(fee)
return result