[프로그래머스] 주차 요금 계산하기 with Python (KAKAO BLIND RECRUITMENT)
-
💡문제
주차장의 요금표와 차량이 들어오고(입차) 나간(출차) 기록이 주어졌을 때, 차량별로 주차 요금을 계산하려고 합니다. 아래는 하나의 예시를 나타냅니다.
어떤 차량이 입차된 후에 출차된 내역이 없다면, 23:59에 출차된 것으로 간주합니다.
0000번 차량은 18:59에 입차된 이후, 출차된 내역이 없습니다. 따라서, 23:59에 출차된 것으로 간주합니다.
00:00부터 23:59까지의 입/출차 내역을 바탕으로 차량별 누적 주차 시간을 계산하여 요금을 일괄로 정산합니다.
누적 주차 시간이기본 시간이하라면,기본 요금을 청구합니다.
누적 주차 시간이기본 시간을 초과하면,기본 요금에 더해서, 초과한 시간에 대해서단위 시간마다단위 요금을 청구합니다.
초과한 시간이단위 시간으로 나누어 떨어지지 않으면,올림합니다.
⌈a⌉: a보다 작지 않은 최소의 정수를 의미합니다. 즉,올림을 의미합니다.
주차 요금을 나타내는 정수 배열fees, 자동차의 입/출차 내역을 나타내는 문자열 배열records가 매개변수로 주어집니다.차량 번호가 작은 자동차부터청구할 주차 요금을 차례대로 정수 배열에 담아서 return 하도록 solution 함수를 완성해주세요.
제한사항
fees의 길이 = 4
fees[0] =기본 시간(분)
1 ≤ fees[0] ≤ 1,439
fees[1] =기본 요금(원)
0 ≤ fees[1] ≤ 100,000
fees[2] =단위 시간(분)
1 ≤ fees[2] ≤ 1,439
fees[3] =단위 요금(원)
1 ≤ fees[3] ≤ 10,000
1 ≤records의 길이 ≤ 1,000
records의 각 원소는"시각 차량번호 내역"형식의 문자열입니다.
시각,차량번호,내역은 하나의 공백으로 구분되어 있습니다.
시각은 차량이 입차되거나 출차된 시각을 나타내며,HH:MM형식의 길이 5인 문자열입니다.
HH:MM은 00:00부터 23:59까지 주어집니다.
잘못된 시각("25:22", "09:65" 등)은 입력으로 주어지지 않습니다.
차량번호는 자동차를 구분하기 위한, `0'~'9'로 구성된 길이 4인 문자열입니다.
내역은 길이 2 또는 3인 문자열로,IN또는OUT입니다.IN은 입차를,OUT은 출차를 의미합니다.
records의 원소들은 시각을 기준으로 오름차순으로 정렬되어 주어집니다.
records는 하루 동안의 입/출차된 기록만 담고 있으며, 입차된 차량이 다음날 출차되는 경우는 입력으로 주어지지 않습니다.
같은 시각에, 같은 차량번호의 내역이 2번 이상 나타내지 않습니다.
마지막 시각(23:59)에 입차되는 경우는 입력으로 주어지지 않습니다.
아래의 예를 포함하여, 잘못된 입력은 주어지지 않습니다.
주차장에 없는 차량이 출차되는 경우
주차장에 이미 있는 차량(차량번호가 같은 차량)이 다시 입차되는 경우
입출력 예 설명
입출력 예 #1
문제 예시와 같습니다.
입출력 예 #2
🙋🏻♀️ How I Thought (구현 실패)
먼저 records에 들어있는 2차원 배열 값들을 나누어야 한다고 생각했다.
그래서 rec_list라는 배열에 공백 기준으로 나누어 배열을 넣었고, 1순위 차량 번호, 2순위 시간 오름차순 기준으로 정렬하였다.
rec_list를 처음 배열부터 돌면서 만약 처음 들어온 값이 입차라면 그다음으로 생각해야할 게 출차를 하는지 안하는지였다. 그래서 rec_list가 시간 순서대로 정렬되어있으므로 뒤에 오는 배열 값이 출차가 아니라면, 23:59분에서 입차된 시간 차이를 구하고 answer 배열에 넣어놨다.
만약 뒤에 오는 배열 값이 출차라면 cal이라는 배열에 현재 차량 번호와 입차시간을 넣어놓은 뒤,
그 다음 배열이 출차일 때, elif문으로 가서 cal에 넣어놓은 입차 시간과 출차시간의 차이를 구한 뒤 answer에 넣어놨다.
이런식으로 모든 차량의 주차시간과 차량번호를 answer에 넣어놓은 뒤 요금을 계산하려하였다.
하지만 내가 짠 코드를 출력해보니 내가 예상했던 결과 값과 다른 값이 나왔다. . .
from datetime import datetime
def solution(fees, records):
answer = []
rec_list= []
cal= []
for i in records:
rec_list.append(list(map(str, i.split())))
rec_list.sort(key=lambda x:(x[1], x[0]))
for i in range(len(rec_list)-1):
if rec_list[i][2] == "IN" or i == len(rec_list) - 1 :
if rec_list[i+1][2] == "IN":
time1 = datetime.strptime("23:59", "%H:%M")
time2 = datetime.strptime(rec_list[i][0], "%H:%M")
diff = str(time1 - time2)
answer.append([rec_list[i][1], diff])
cal.append(datetime.strptime(rec_list[i][0], "%H:%M"))
elif rec_list[i][2] == "OUT":
fee = datetime.strptime(rec_list[i][0], "%H:%M") - cal[0]
answer.append([rec_list[i][1], str(fee)])
fee = 0
return answer
🙆🏻♀️ How to Solve
다른 분들의 코드를 참고하여 이해하였다.
먼저 records에 공백으로 나뉘어진 값들을 각각 time, number, io에 저장해두고, time은 HH:MM 형식이므로
시를 분으로 계산하기 편하도록 변환해준다.
만약 들어온 차량이 입차라면 car[차량번호] 에 입차 분을 저장해두고, 출차한다면 출차하는 분과 입차했던 분의 차이를 계산해준다.
만약 times에 이미 똑같은 차량번호로 저장되어있는 값이 있다면 그 값에 더 해주고, 아니면 times[차량번호] 에 계산 값을 넣어준다.
이때 출차하면 차는 이미 나갔기 때문에 car[차량번호]에서 제거해준다.
그렇게 되면 car배열에는 입차하고 출차가 안된 차량들만 남는다.
이 차량들은 23:59분에서 입차된 시간을 뺴준 뒤, times 배열에 위와 같이 넣어준다.
후에 times배열에 저장되어있는 차량번호 별 주차시간으로 주차 요금을 계산해준 뒤, 차량번호를 오름차순으로 정렬하여 출력해주면 된다.
import math
def solution(fees, records):
answer= []
times = {}
car = {}
for i in records:
time, number, io = i.split()
hour, minute = time.split(':')
minutes = int(hour) * 60 + int(minute)
if io == "IN":
car[number] = minutes
elif io == "OUT":
time = minutes - car[number]
if number in times:
times[number] += time
else:
times[number] = time
del(car[number])
for key, val in car.items():
time = 23 * 60 +59 - val
if key in times:
times[key] += time
else:
times[key] = time
for key,val in times.items():
time= max(0, val- fees[0])
money = fees[1] + math.ceil(time/fees[2]) * fees[3]
times[key] = money
times = sorted(times.items())
for key, val in times:
answer.append(val)
return answer