다리를 지나는 트럭 문제 바로가기

나의 풀이

from collections import deque

def solution(bridge_length, weight, truck_weights):
    time = 0
    
    bridge = [0] * bridge_length
    bridge_sum = 0
    
    bridge = deque(bridge)
    truck_weights = deque(truck_weights)
    
    while truck_weights:
        bridge_sum -= bridge[-1]
        bridge.pop()
        time += 1
        if bridge_sum + truck_weights[0] <= weight:
            bridge.insert(0, truck_weights.popleft())
        else:
            bridge.insert(0, 0)
        bridge_sum += bridge[0]
    time += bridge_length
    return time

고수의 풀이

import collections

DUMMY_TRUCK = 0


class Bridge(object):

    def __init__(self, length, weight):
        self._max_length = length
        self._max_weight = weight
        self._queue = collections.deque()
        self._current_weight = 0

    def push(self, truck):
        next_weight = self._current_weight + truck
        if next_weight <= self._max_weight and len(self._queue) < self._max_length:
            self._queue.append(truck)
            self._current_weight = next_weight
            return True
        else:
            return False

    def pop(self):
        item = self._queue.popleft()
        self._current_weight -= item
        return item

    def __len__(self):
        return len(self._queue)

    def __repr__(self):
        return 'Bridge({}/{} : [{}])'.format(self._current_weight, self._max_weight, list(self._queue))


def solution(bridge_length, weight, truck_weights):
    bridge = Bridge(bridge_length, weight)
    trucks = collections.deque(w for w in truck_weights)

    for _ in range(bridge_length):
        bridge.push(DUMMY_TRUCK)

    count = 0
    while trucks:
        bridge.pop()

        if bridge.push(trucks[0]):
            trucks.popleft()
        else:
            bridge.push(DUMMY_TRUCK)

        count += 1

    while bridge:
        bridge.pop()
        count += 1

    return count


def main():
    print(solution(2, 10, [7, 4, 5, 6]), 8)
    print(solution(100, 100, [10]), 101)
    print(solution(100, 100, [10, 10, 10, 10, 10, 10, 10, 10, 10, 10]), 110)


if __name__ == '__main__':
    main()

출처

CODE REVIEW

  1. queue을 이용한 기발한 문제. 처음에는 도대체 어떻게 풀어야할까 망설였는데, [0] * bridge_length의 배열을 생각해서 한 칸씩 민다고 생각하니까 금세 풀렸다.
  2. 답안을 제출하다보면 테스트 케이스 5번에서 자꾸만 시간초과 에러가 발생한다. 이는 전체 무게를 한계 무게와 비교할 때 발생하는데, sum()을 사용해서 전체 무게를 구하기보다는 그때그때 bridge_sum에 들어오는 차량은 무게를 더해주고, 나가는 차량은 빼주는 방식으로 처리해야 시간 초과 에러를 피할 수 있다.
  3. 고수의 풀이를 참고해보니 class로 구현한 답안이 있어 가져와봤다. 전체적인 논리는 비슷하지만, 확실히 solution 함수의 가독성이 매우 좋아진다는 점에서 따봉👍👍을 날려주고 싶다.