프로그래머스_주차요금계산

임정민·2023년 8월 9일
1

알고리즘 문제풀이

목록 보기
84/173
post-thumbnail

프로그래머스 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에 모든 차량의 주차 시간을 저장하는 방식이었습니다.🐳🐳🐳

감사합니다.

profile
https://github.com/min731

0개의 댓글