Python/알고리즘 문제 풀이

[코테] 주차 요금 계산

마이구미+ 2023. 8. 9. 12:37

문제링크

 

프로그래머스

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

programmers.co.kr

<로직 고민/>

  • 차근차근 해보자..
  • 우선, records에서 차량번호를 split 해서 중복 제거 후 주차장에 들어온 차량 리스트를 만든다(결과를 차량번호순으로 반환하라고 했으므로 sort() 메서드로 정렬을 해준다!)
  • 그 다음 누적 주차 시간을 담아야 하는데, 내역을 for문으로 돌리면서 각 차량 번호별로 계산해야 하므로 딕셔너리를 사용하는 게 적절하다고 판단했다
  • 차량번호 리스트를 이용해서 누적 주차 시간을 담을 딕셔너리를 만든다
  • 이제 records를 for문에 돌려가며 누적 주차 시간을 계산할 건데, 주차장에 들어오고 나가지 않은 차를 선별하기 위해 parking이라는 리스트를 선언해서 차량번호별로 IN이면 append하고 OUT이면 remove 하며 입/출차 리스트를 관리한다
  • records를 split해서 time, number, status로 나눠준다
  • status가 IN이면 parking 리스트에 해당 number를 담고, 차량별 누적 시간 딕셔너리에 time을 음수로 더해준다
  • status가 OUT이면 parking 리스트에서 해당 number를 제거하고, 차량별 누적 시간 딕셔너리에 time을 양수로 더한다
  • for문이 다 돌고 parking 리스트가 빈 리스트가 아니면 parking 리스트를 돌리면서 해당 번호에 해당하는 차량의 누적 시간에 1439(23*60+59)를 더한다
  • cars 리스트를 for문에 돌리면서 각 차량별 주차 요금을 계산한다
  • [초과한 시간이 단위 시간으로 나누어 떨어지지 않으면, 올림합니다.] 이 부분은 어제 배운대로 ceil 함수 없이 올림하는 거 적용해봐야지!
  • 그리고 기본 시간보다 누적 주차 시간이 적은 차량 예외처리도 if-else문으로 처리하면 끝!

<완성된 풀이/>

def solution(fees, records):
    # 주차장에 들어온 차량 리스트 만들기
    cars = []
    for car_number in records:
        cars.append(car_number.split(" ")[1])
        cars = list(set(cars))  # 중복 제거
    cars.sort()  # 차량번호순으로 정렬

    # 각 차량별 누적 주차 시간을 담을 딕셔너리 만들기
    parking_times = dict.fromkeys(cars, 0)

    # 내역에 따른 각 차량별 누적 주차 시간 계산하기
    parking = []
    for record in records:
        time = (int(record.split(" ")[0].split(":")[0]) * 60) + int(
            record.split(" ")[0].split(":")[1]
        )
        number = record.split(" ")[1]
        status = record.split(" ")[2]
        if status == "IN":
            parking.append(number)
            parking_times[number] += -time
        else:
            parking.remove(number)
            parking_times[number] += time

    # 주차장 OUT이 없는 차량 누적 주차시간 계산하기
    if len(parking) != 0:
        for n in parking:
            parking_times[n] += 1439

    # 각 차량별 요금 계산하기
    answer = []
    for car in cars:
        if parking_times[car] > fees[0]:
            answer.append(
                fees[1] + (-((fees[0] - parking_times[car]) // fees[2])) * fees[3]
            )
        else:
            answer.append(fees[1])
    return answer

<다른 사람 풀이/>

- 천재풀이1

from collections import defaultdict
from math import ceil

class Parking:
    def __init__(self, fees):
        self.fees = fees
        self.in_flag = False
        self.in_time = 0
        self.total = 0

    def update(self, t, inout):
        self.in_flag = True if inout=='IN' else False
        if self.in_flag:  self.in_time = str2int(t)
        else:             self.total  += (str2int(t)-self.in_time)

    def calc_fee(self):
        if self.in_flag: self.update('23:59', 'out')
        add_t = self.total - self.fees[0]
        return self.fees[1] + ceil(add_t/self.fees[2]) * self.fees[3] if add_t >= 0 else self.fees[1]

def str2int(string):
    return int(string[:2])*60 + int(string[3:])

def solution(fees, records):
    recordsDict = defaultdict(lambda:Parking(fees))
    for rcd in records:
        t, car, inout = rcd.split()
        recordsDict[car].update(t, inout)
    return [v.calc_fee() for k, v in sorted(recordsDict.items())]
  • 진짜 대박이다...
  • class 사용할 생각을 못 했군...

<수정/>

  • 내 풀이 15~19번째 줄이 지저분하다고 생각했는데 다른 사람 풀이를 보니까 아 저렇게도 됐었지 싶어서 수정했다

- 수정한 부분

        time, number, status = record.split(" ")
        time = int(time.split(":")[0]) * 60 + int(time.split(":")[1])

- 전체 코드

def solution(fees, records):
    # 주차장에 들어온 차량 리스트 만들기
    cars = []
    for car_number in records:
        cars.append(car_number.split(" ")[1])
        cars = list(set(cars))  # 중복 제거
    cars.sort()  # 차량번호순으로 정렬

    # 각 차량별 누적 주차 시간을 담을 딕셔너리 만들기
    parking_times = dict.fromkeys(cars, 0)

    # 내역에 따른 각 차량별 누적 주차 시간 계산하기
    parking = []
    for record in records:
        time, number, status = record.split(" ")
        time = int(time.split(":")[0]) * 60 + int(time.split(":")[1])
        if status == "IN":
            parking.append(number)
            parking_times[number] += -time
        else:
            parking.remove(number)
            parking_times[number] += time

    # 주차장 OUT이 없는 차량 누적 주차시간 계산하기
    if len(parking) != 0:
        for n in parking:
            parking_times[n] += 1439

    # 각 차량별 요금 계산하기
    answer = []
    for car in cars:
        if parking_times[car] > fees[0]:
            answer.append(
                fees[1] + (-((fees[0] - parking_times[car]) // fees[2])) * fees[3]
            )
        else:
            answer.append(fees[1])
    return answer