문제
문제 설명
주차장의 요금표와 차량이 들어오고(입차) 나간(출차) 기록이 주어졌을 때, 차량별로 주차 요금을 계산하려고 합니다. 아래는 하나의 예시를 나타냅니다.
- 요금표
기본 시간(분) 기본요금(원) 단위 시간(분) 단위 요금(원)
180 | 5000 | 10 | 600 |
- 입/출차 기록
시각(시:분)차량 번호 내역
05:34 | 5961 | 입차 |
06:00 | 0000 | 입차 |
06:34 | 0000 | 출차 |
07:59 | 5961 | 출차 |
07:59 | 0148 | 입차 |
18:59 | 0000 | 입차 |
19:09 | 0148 | 출차 |
22:59 | 5961 | 입차 |
23:00 | 5961 | 출차 |
- 자동차별 주차 요금
차량 번호 누적 주차 시간(분) 주차 요금(원)
0000 | 34 + 300 = 334 | 5000 + ⌈(334 - 180) / 10⌉ x 600 = 14600 |
0148 | 670 | 5000 +⌈(670 - 180) / 10⌉x 600 = 34400 |
5961 | 145 + 1 = 146 | 5000 |
- 어떤 차량이 입차 된 후에 출차된 내역이 없다면, 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)에 입차 되는 경우는 입력으로 주어지지 않습니다.
- 아래의 예를 포함하여, 잘못된 입력은 주어지지 않습니다.
- 주차장에 없는 차량이 출차되는 경우
- 주차장에 이미 있는 차량(차량번호가 같은 차량)이 다시 입차되는 경우
입력 & 출력
입출력 예
feesrecordsresult
[180, 5000, 10, 600] | ["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"] | [14600, 34400, 5000] |
[120, 0, 60, 591] | ["16:00 3961 IN","16:00 0202 IN","18:00 3961 OUT","18:00 0202 OUT","23:58 3961 IN"] | [0, 591] |
[1, 461, 1, 10] | ["00:00 1234 IN"] | [14841] |
풀이 과정
코드 실행을 하면 기본적으로 공개되어있는 테스트 케이스는 전부 통과를 하지만 제출을 하였을 때는 실패를 하는 풀이입니다.
향후 반례를 찾아서 추가시킬 예정입니다.
- 해당 구현 간략 설명
1. 차량마다의 주차시간을 저장하는 로직과 계산하는 로직을 분리시켜야 된다고 생각하였습니다.
2. 차량 번호마다 이용한 시간을 하루 단위로 처리하기 때문에 딕셔너리를 구성하여 해당 내용이 저장될 수 있게 준비합니다.
3. 들어오는 records 값을 for문으로 하나씩 순회하면서 볼 때 인덱스 값을 이용하여 IN 값인지 OUT 값인지 확인한다. 이 내용에서는 IN과 OUT이 글자 수의 차이도 나고 두 가지 경우만 있으므로 길이를 이용하여 판별하여도 됩니다.
4. IN 일 경우는 packing_in이라는 배열에 해당 값을 붙여 넣어두고 OUT이 나왔을 때 차량 번호 값을 이용하여 in에 정리되어있는 내용을 찾도록 합니다.
5. 4번에서 for문을 순회하면서 찾으면서 해당 for문이 몇 번째 경우인지를 판별하여 index 값을 사용하기 위하여 enumerate를 사용합니다.
6. IN으로 들어온 값과 OUT으로 들어온 값의 시간 문자열을 가공하여 시와 분으로 데이터를 분리시키고 시간에는 60을 곱하여 분으로 단위를 치환하고 이 내용을 이용하여 주차 시간을 구합니다.
7. 해당 내용을 이용하여 첫 번째로 자동차번호가 딕셔너리에 저장되게 된다면 키와 밸류 값으로 하여 해당 값을 저장하고 만약에 자동차번호가 딕셔너리에 이미 있는 값이라면 있는 값에 저장된 주차시간에 계산된 값을 더하는 방식으로 총 주차시간을 업데이트하도록 합니다.
8. 이렇게 값을 딕셔너리에 추가하게 되면 OUT 값이 나온 순서에 따라서 자동차의 주차시간 정보가 저장되게 되는데 이것을 밑과 같이 자동차 번호 값을 기준으로 정렬하여 줍니다.
sorted_answer = sorted(answer.items(), key=lambda x: x[0])
9. 이렇게 이미 정렬을 해두었기 때문에 이 순서를 이용하여 최종 출력 값을 정해줍니다. 최종 출력 값에는 자동차의 번호 순서대로 정렬되어있는 주차 요금이 나오면 되기 때문에 fees 배열의 각각의 인덱스 값의 의미를 생각하면서 sorted_answer의 주차시간에 따라서 result 값을 추가해줍니다.
- 위 내용에서는 주어진 조건식대로만 작성하면 특별한 문제는 없겠지만 제약 조건에서 나누어 떨어지지 않을 때 같은 문제를 구현하기 위하여 % 연산자를 이용하여 나누어 떨어지는지 여부를 판별하는 조건문이 필요합니다.
10. 이렇게 구현이 가능하고 생각이 되는 테스트 케이스는 전부 통과를 하는데 제출 시 문제가 있어서 반례를 생각해보고 있습니다.
- 이상 중간 기록을 마칩니다.
코드
def solution(fees, records):
answer = {}
parking_in = []
result = []
for record in records:
if record.split()[2] == "IN":
parking_in.append(record)
elif record.split()[2] == "OUT":
for i, parking_in_unit in enumerate(parking_in):
if record.split()[1] in parking_in_unit.split()[1]:
in_time = parking_in.pop(i).split()[0]
out_time = record.split()[0]
in_time_h = int(in_time.split(":")[0])
in_time_m = int(in_time.split(":")[1])
out_time_h = int(out_time.split(":")[0])
out_time_m = int(out_time.split(":")[1])
total_in_time = in_time_h * 60 + in_time_m
total_out_time = out_time_h * 60 + out_time_m
parking_time = total_out_time - total_in_time
if record.split()[1] not in answer:
answer[record.split()[1]] = parking_time
else:
answer[record.split()[1]] = answer[record.split()[1]] + parking_time
if parking_in:
for i, parking_in_unit in enumerate(parking_in):
in_time = parking_in.pop(i).split()[0]
in_time_h = int(in_time.split(":")[0])
in_time_m = int(in_time.split(":")[1])
total_in_time = in_time_h * 60 + in_time_m
total_out_time = 23 * 60 + 59
parking_time = total_out_time - total_in_time
if parking_in_unit.split()[1] not in answer:
answer[parking_in_unit.split()[1]] = parking_time
else:
answer[parking_in_unit.split()[1]] = answer[parking_in_unit.split()[1]] + parking_time
print(answer)
sorted_answer = sorted(answer.items(), key=lambda x: x[0])
print(sorted_answer)
for sort in sorted_answer:
if sort[1] <= fees[0]:
cost = fees[1]
result.append(cost)
else:
if (sort[1] - fees[0]) % fees[2] > 0:
cost = ((sort[1] - fees[0]) // fees[2] + 1) * fees[3] + fees[1]
result.append(cost)
else:
cost = ((sort[1] - fees[0]) // fees[2]) * fees[3] + fees[1]
result.append(cost)
return result
'Algorithm' 카테고리의 다른 글
[프로그래머스] 평행 (0) | 2022.10.04 |
---|---|
[프로그래머스] 점프와 순간 이동 (0) | 2022.09.27 |
[프로그래머스] 양궁 대회 (0) | 2022.09.27 |
[ETC] 이전 숫자들의 합을 마지막 숫자로 받는 문자열 출력 (0) | 2022.09.26 |
[ETC] 파일 이름 저장하기 (0) | 2022.09.26 |