프로그래머스 2022 KAKAO BLIND RECRUITMENT 문제입니다.실전에 대비하기 위해 60분 시간제한을 두고 풀었습니다.
문제
https://school.programmers.co.kr/learn/courses/30/lessons/92341
[나의 풀이]
⌛ 시간초과
def solution(fees, records):
from collections import deque
import math
answer = []
basic_time = fees[0] # 기본 무료 시간
basic_fee = fees[1] # 기본 요금
per_time = fees[2] # 단위 시간
per_fee = fees[3] # 단위 시간당 요금
data = {}
for record in records:
record = record.split()
time = record[0]
time = time.split(':')
# 시간 '분'으로 통합
time = int(time[0])*60+int(time[1])
num = record[1]
inOut = record[2]
# 05:34 5961 IN
if num not in data.keys():
data[num] = {}
if inOut not in data[num].keys():
data[num][inOut] = deque([])
data[num][inOut].append(time)
# 차량 번호 순으로 정렬
numbers = sorted(data.keys())
for number in numbers:
total_time = 0
In = data[number]['IN']
# 출차하지 않았을 시
if 'OUT' not in data[number].keys():
total_time += 1439-In[0]
if total_time<=basic_time:
answer.append(basic_fee)
else:
answer.append(int(basic_fee+math.ceil((total_time-basic_time)/per_time)*per_fee))
continue
# In = data[number]['IN']
Out = data[number]['OUT']
# In 하고 Out이 있을 때까지
while Out:
v_in = In.popleft()
v_out = Out.popleft()
total_time += v_out-v_in
if In:
total_time += 1439-In[0]
if total_time<=basic_time:
answer.append(basic_fee)
else:
answer.append(int(basic_fee+math.ceil((total_time-basic_time)/per_time)*per_fee))
return answer
주차장에 들어오는 차량의 시간을 계산하여 주차 시간,기본 요금, 시간당 요금을 계산하는 문제입니다. 전체적으로 이해하기는 어렵지 않은 문제였지만 세부적으로 까다로워 60분이 조금 지난 뒤에 해결할 수 있었습니다.🐱🐱🐱
구현 포인트는 입차/출차 시간을 '분'으로 통합하여 요금을 계산하기 쉬운형태로 변환해주는 것과 입차는 하였지만 출차하지 않은 케이스는 23:59에 출차한다고 가정하여 계산하는 부분이었습니다.
또한 차량이 입차후 출차하기 때문에 차량 번호로 구분된 k(차량번호),v(주차정보) 형태의 v를 queue 구조로 구현하였습니다.
[다른사람의 풀이]
import math
# fees: [기본 시간(분), 기본 요금(원), 단위 시간(분), 단위 요금(원)]
def get_fee(minutes, fees):
return fees[1] + math.ceil(max(0, (minutes - fees[0])) / fees[2]) * fees[3]
def solution(fees, records):
parking = dict()
stack = dict()
for record in records:
time, car, cmd = record.split()
hour, minute = time.split(":")
minutes = int(hour) * 60 + int(minute) # 시간 -> 분 환산
if cmd == 'IN':
parking[car] = minutes
elif cmd == 'OUT':
try:
stack[car] += minutes - parking[car]
except:
stack[car] = minutes - parking[car]
del parking[car] # 출차 차량 삭제
# 출차 기록 없는 차 23:59 출차 처리
for car, minute in parking.items():
try:
stack[car] += 23*60+59 - minute
except:
stack[car] = 23*60+59 - minute
return [get_fee(time, fees) for car, time in sorted(list(stack.items()), key=lambda x: x[0])]
방금 주차한 내역을 parking이라는 딕셔너리에 저장하고 stack이라는 딕셔너리에 각 차량별 주차 시간을 저장하여 해결한 풀이입니다.
해당 풀이의 포인트는
if cmd == 'IN':
parking[car] = minutes
elif cmd == 'OUT':
try:
stack[car] += minutes - parking[car]
except:
stack[car] = minutes - parking[car]
del parking[car] # 출차 차량 삭제
조건문입니다. 문제에서 주어지는 입력값이 시간 순서대로 들어오기 때문에 같은 차량이라면 'IN' 다음 'OUT'들어옵니다. 이 때문에 1) 'IN' 2) 'OUT' 순서대로 체크해도 이상이 없으며 제가 해결할 때에는 입력값이 시간순서가 아닌 무작위로 들어오는 줄 착각하여 생각하지 못했습니다.🐥🐥🐥
또 한가지 포인트는 except 구문입니다. stack 딕셔너리 객체에 주차 시간을 누적할 때 최초에는 키가 없기 때문에 보통 if newKey not in stack.keys()과 같은 구문으로 해결하지만 except 처리하여 간결하게 넘어갈 수 있었습니다.
그 다음 포인트로 주차 시간이 계산된 IN-OUT 쌍은 parking에서 삭제하고,
입차만 하고 출차하지 않은 케이스(parking에 남은 케이스)만 따로 계산하여 결론적으로 stack에 모든 차량의 주차 시간을 저장하는 방식이었습니다.🐳🐳🐳
감사합니다.