[프로그래머스] Lv2 - 주차 요금 계산

김멉덥·2023년 8월 5일
0

알고리즘 공부

목록 보기
83/171
post-thumbnail
post-custom-banner

문제

프로그래머스 2022 KAKAO BLIND RECRUITMENT


코드 구현

import math

def solution(fees, records):
    answer = []

    car_record = dict()     # 입차한 차의 시간을 기록해놔서 출차하는 같은 차번호를 발견할 때 꺼내서 계산하기 위한 사전
    ans_record = dict()     # 해당 차 번호에 대한 누적 주차 시간을 계산해서 저장할 사전

    for r in records:
        rec = list(r.split(" "))

        # 입차하는 차라면
        if(rec[2] == "IN"):
            car_record[rec[1]] = rec[0]         # car_record 에 기록
            if(int(rec[1]) not in ans_record):  # ans_record 에 없는 차라면 시간 0으로 새로 넣어주기 (추후 key값의 정렬을 위해 차 번호는 int형으로 넣어줌)
                ans_record[int(rec[1])] = 0

        # 출차하는 차라면
        elif(rec[2] == "OUT"):
            in_time = car_record.get(rec[1])    # 출차하는 차 번호를 가지고 입차한 시간 기록을 얻기
            out_time = rec[0]       # 출차 시간

            # 시간 계산
            calculated_time = round(((int(out_time.split(":")[0]) + (int(out_time.split(":")[1]) / 60)) - (int(in_time.split(":")[0]) + (int(in_time.split(":")[1]) / 60))) * 60)
            # print(calculated_time)

            ans_record[int(rec[1])] += calculated_time      # 누적 주차 시간 기록하기
            car_record.pop(rec[1])      # 출차했으니까 입차 기록에서 제거

    # 입차한 차가 남아있으면 -> 입차 이후 출차한 내역이 없는 차
    if(len(car_record) > 0):
        for c in car_record:
            # 23:59에 출차된 것으로 간주해서 계산하기
            calculated_time = round(abs(((23 + (59 / 60)) - (int(car_record[c].split(":")[0]) + (int(car_record[c].split(":")[1]) / 60))) * 60))
            ans_record[int(c)] += calculated_time       # 누적 주차 시간에 기록하기

    # 차량 번호가 작은거부터 정답을 출력해야하니 정렬하기
    ans_record = sorted(ans_record.items())

    # 요금 계산해서 정답 배열에 넣기
    for i in ans_record:
        if (i[1] <= fees[0]):       # 기본 시간 이하라면 -> 기본 요금 청구
            cal_fee = fees[1]
        else:                       # 기본 시간을 초과하면 -> 기본 요금 + 단위 시간마다 단위 요금을 청구
            cal_fee = fees[1] + (math.ceil((i[1] - fees[0]) / fees[2]) * fees[3])
        answer.append(cal_fee)


    return answer

if __name__ == '__main__':
    print(solution([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"]))

풀이

  • 문제 풀이 전 주석 기록, TODO 정리
# 입차 -> 출차 X : 23:59 출차로 계산
# 누적 주차 시간 <= 기본 시간 -> 기본 요금
# 누적 주차 시간 > 기존 시간 -> 기본 요금 + 초과 시간 (나누어 떨어지지 않으면 올림 계산)
# fee == [기본 시간, 기본 요금, 단위 시간, 단위 요금]

## TODO
### IN 이면 -> 차량 번호 사전에 기록
### OUT 이면 -> 사전에서 차량번호 찾아서 시간 계산
### 시간 계산은 -> (시간 + 분 / 60) * 60 의 반올림
### 계산하고 나서 사전에서 제거 -> 마지막에 사전에 남아있는 차들은 아직 출차 못한 차 -> 23:59로 계산
  • 시간 계산을 하는 부분이 생각보다 오래 걸렸다. → 디버깅을 해보니 전체를 감싸는 괄호의 유무 차이로 값이 달라져서 그랬던 것 !! ㅠㅠ
  • 요금 계산에서는 round()가 아닌 ceil()을 써줘야 확실하게 올림이 되어서 이상한 값이 나오지 않는다.
  • 로직을 생각하는건 어려운 문제가 아닌데 짜다보니 길어져서 틀리는 부분을 파악하기가 조금 오래 걸리는 문제였던 것 같다.

What I learned

▶️ math.ceil() : 올림
참고 : https://dpdpwl.tistory.com/94

▶️ 파이썬 딕셔너리 정렬 → Key를 오름차순하여 튜플 형태로 (Key, Value) 반환
참고 : https://cocobi.tistory.com/203

dic = {'e': 1, 'a': 3, 'b': 5, 'c': 1, 'd': 2, }
dic = sorted(dic.items())

print(dic) 
#[('a', 3), ('b', 5), ('c', 1), ('d', 2), ('e', 1)]

아무런 옵션 없이 dicsorted 했을 경우 Key만을 정렬한 리스트를 반환하기 때문에 값도 같이 가져가야 한다면 dic.items()로 정렬해주어야 한다.

profile
데굴데굴 뚝딱뚝딱 개발기록
post-custom-banner

0개의 댓글