CS/algorithm & data structure

[프로그래머스] 주차 요금 계산 (파이썬 풀이)

hjkim0502 2022. 7. 6. 18:07

https://school.programmers.co.kr/learn/courses/30/lessons/92341

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

 

* 내 풀이:

from math import ceil
from collections import defaultdict

def solution(fees, records):
    table = defaultdict(lambda : [0])
    # 각 차량의 입출차 기록 딕셔너리에 저장 및 첫 정보는 각 차량별 기록 갯수
    for record in records:
        time, num, inout = record.split()
        h, m = time.split(':')
        table[num].append('+' + str(int(h) * 60 + int(m)))
        table[num][0] += 1
    
    
    ans = []
    # 번호가 작은 순서대로
    for num in sorted(table):
        # 기록 갯수가 홀수라면 23:59에 출차한 것으로 간주
        if int(table[num][0]) % 2:
            table[num].append(str(23 * 60 + 59))
        
        # 각 차량별로 총 주차한 시간 구하여 요금 계산
        for i in range(0, len(table[num]), 2):
            table[num][i] = '-' + str(table[num][i])
        all_time = -eval(''.join(table[num][1:]))
        if all_time <= fees[0]:
            ans.append(fees[1])
        else:
            fee = fees[1] + ceil((all_time - fees[0]) / fees[2]) * fees[3]
            ans.append(fee)
            
    return ans
  • 아이디어: 잘못된 정보(입출차 기록, 숫자 등)는 주어지지 않으므로 각 차량별로 주어진 기록을 쭉 나열하면 이를 활용해 총 주차 시간 구할 수 있겠다고 생각함
  • 각 차량별 기록 갯수 활용해 23:59로 처리할 것은 처리한 후, 미리 부호로 처리한 문자열들을 eval으로 한번에 계산

* 차량별 기록 갯수 저장하지 않은 풀이:

from math import ceil
from collections import defaultdict

def solution(fees, records):
    table = defaultdict(list)
    for record in records:
        time, num, inout = record.split()
        h, m = time.split(':')
        table[num].append('+' + str(int(h) * 60 + int(m)))

    ans = []
    for num in sorted(table):
        if len(table[num]) % 2:
            table[num].append(str(23 * 60 + 59))

        for i in range(1, len(table[num]), 2):
            table[num][i] = '-' + str(table[num][i])
            
        all_time = -eval(''.join(table[num]))
        if all_time <= fees[0]:
            ans.append(fees[1])
        else:
            ans.append(fees[1] + ceil((all_time - fees[0]) / fees[2]) * fees[3])
            
    return ans
  • 시간 효율 비슷하므로 이 풀이가 더 나을 듯 함

* eval 쓰지 않은 개선된 풀이:

from math import ceil
from collections import defaultdict

def solution(fees, records):
    table = defaultdict(list)
    for record in records:
        time, num, inout = record.split()
        h, m = time.split(':')
        table[num].append((int(h) * 60 + int(m), inout))

    temp, ans = 0, []
    for num in sorted(table):
        if len(table[num]) % 2:
            table[num].append((23 * 60 + 59, 'OUT'))

        for time, inout in table[num]:
            if inout == 'IN':
                temp += -time
            else:
                temp += time
                
        if temp <= fees[0]:
            ans.append(fees[1])
        else:
            ans.append(fees[1] + ceil((temp - fees[0]) / fees[2]) * fees[3])
        temp = 0
            
    return ans
  • 시간 효율과 가독성이 훨씬 좋아짐