고딩왕 코범석

[프로그래머스] 셔틀버스, Python3 본문

Computer Science/Algorithm

[프로그래머스] 셔틀버스, Python3

고딩왕 코범석 2021. 1. 29. 13:38
반응형

문제는 여기!

저번에 풀었던 추석 트래픽 문제에서 시간 계산하는 과정이 비슷했던 문제다. 문제를 풀이하고 나서 22번 테스트 케이스가 런타임 에러가 나서 질문하기 게시판을 참조하였다. 이 부분은 제한사항 및 주의사항에서 설명하겠다.

제한사항 및 주의사항

셔틀은 항상 09:00 부터 운행하며 n = 운행 횟수, t = 운행하는 시간 간격, m = 한 셔틀버스에 탑승할 수 있는 최대 승객


다음날 셔틀을 타는 일은 없으며, 콘이 셔틀을 타고 사무실을 갈 수 있는 제일 늦은 시간 구하기


0 < n <= 10

0 < t <= 60

0 < m <= 45

1 <= len(timetable) <= 2,000 해당 배열의 원소들은 "HH:MM" 형식으로 이루어져 있고 크루의 도착시각은 "00:01" ~ "23:59" 까지다.


하지만 22번 테스트 케이스에 24:00 시간이 있어 런타임 에러가 발생한다길래 문제에서 24:00은 23:59로 고쳐주었다.

풀이전략

우선 time 변수에 버스가 출발하는 시간인 09:00을 datetime으로 변환 후 저장했다.


bus_time 리스트는 버스가 출발하는 시간들을 저장하고, bus_passenger 딕셔너리는 버스가 출발하는 시간을 키, 해당 시간대에 타는 크루들을 담는 배열을 value로 선언했다. 이를 n만큼 반복문을 통해 세팅하고, 버스가 출발하는 시간인 time을 timedelta 메서드를 통해 연산을 해주어 t만큼 증가시켰다.


문제를 보니 timetable을 주어지는 순서에 대해 언급이 없어서 sort처리 해주었다. 정렬된 timetable을 반복문을 통해 버스의 도착시간에 맞게 bus_passenger 딕셔너리에 넣어주자.


크루원을 버스에 태울 때 체크해야할 것은 크루원의 도착시간이 버스 도착시간보다 같거나 빨라야한다. bus_time 리스트를 for문으로 돌려 bus_time과 크루원의 도착시간을 비교, bus_time에 버스 탑승 승객 제한인원을 체크해서 집어넣고 반복문을 break 하자. 이 과정으로 버스가 출발하는 시간들과 해당 시간에 탑승한 승객이 누군지 표현했다.


이제 답을 구할 시간이다. 콘은 결국 셔틀을 타고 회사에 갈 수 있는 가장 늦은 줄서는 시간을 구하면 된다. 이 때, 마지막 버스에 자리가 있을 경우는 마지막 버스 시간에 맞춰 "HH:MM"을 리턴하면 된다. 만약 마지막 버스에 정원이 다 차있을 경우, 마지막 버스에 탑승한 크루들의 줄을 섰던 시간대(리스트)에서 최댓값을 구한 다음, 1분을 단축시켜 리턴하면 답을 구할 수 있다.

import datetime


def solution(n, t, m, timetable):
    time = datetime.datetime.strptime("09:00", '%H:%M')
    bus_time = []
    bus_passenger = {}
    for i in range(n):
        bus_time.append(time)
        bus_passenger[time] = []
        time += datetime.timedelta(minutes=t)

    # 24:00이 주어지므로 치환하기
    for i in range(len(timetable)):
        if timetable[i] == "24:00":
            timetable[i] = "23:59"

    timetable.sort()
    for time in timetable:
        passenger = datetime.datetime.strptime(time, '%H:%M')
        for i in range(len(bus_time)):
            if passenger <= bus_time[i] and len(bus_passenger[bus_time[i]]) < m:
                bus_passenger[bus_time[i]].append(passenger)
                break

    if len(bus_passenger[bus_time[n - 1]]) < m:
        return str(bus_time[n - 1]).split()[1][:5]
    elif len(bus_passenger[bus_time[n - 1]]) == m:
        times = bus_passenger[bus_time[n - 1]]
        return str(times[-1] - datetime.timedelta(minutes=1)).split()[1][:5]
반응형