카테고리 없음

[Python] 프로그래머스 다리를 지나는 트럭

위시리 2024. 10. 15. 21:43

알고리즘 고득점 kit - 스택/큐 - lv 2

 

문제 분석

  • 트럭이 일차선 다리를 건널건데
  • 모든 트럭이 다리를 다 건너려면 최소 몇초가 걸리는가
  • 다리에 올라갈 수 있는 최대 트럭 수 : bridge_length
  • 최대 무게 : weight
  • 다리 위에 올라간 트럭의 무게만 고려
  • 트럭이 다리를 건너는 최소 시간 return

 

코드 설계

  • 대기 트럭 맨 앞부터 최대 올라갈 수 있는 트럭 수까지 append 시도
  • 만약 다리 위의 트럭의 무게 합이 10이 넘으면 넘지 않는 만큼만 올리고 맨 앞만 pop(0)
  • 종료조건 : 대기 트럭 배열의 값이 없을 때
  •  
  • 시간 언제 계산? : 다리 위에 append, 이동하는 시간 계산
  • 왜 맨 처음 트럭이 다리 위에 올라가기만 했는데 1-2초나 걸린거지?
  • >> 트럭이 다리 위에 올라와서 움직이는 시간도 고려해야함
    • ex) 최대 10이 올라갈 수 있는 길이 2인 다리라면
    • 1초 : [ ] [7]
    • 2초 : [7] [ ]
    • 그래서 1-2초 걸림
    • 그러면 다리에 올라오고, 다리를 건너는 동안의 시간에 따라 시간을 계산
  • 대기 트럭 배열 값이 모두 없어질 때까지 반복
  • 맨 앞의 트럭이 다리에 올라갈 수 있는지 확인
    • 다리 배열의 값들의 합 + 올라갈 트럭 < 최대 무게
    • 다리에 append 하고 time += 1
    • else : # 다리에 못올라감
    • 그러면 맨 앞의 트럭은 다리 끝까지 이동해서 return : 이때 이동하는 거리만큼 time += 1
    • pop(0)하면 다시 다리 위에 올라가도 되는지 검사

 

정답 코드

실패..

from collections import deque
def solution(bridge_length, weight, trucks):
    time = 0
    bridge = deque()
    while trucks :
        for _ in range(bridge_length) :
            time += 1
            if (sum(bridge) + trucks[0] < weight) :
                bridge.append([trucks[0]])
                trucks.pop(0) # 다리 위에 올리고 대기 트럭에서는 지우기
            else :
                continue
    return time

 

다른 사람 코드 1 - chatGPT

from collections import deque

def solution(bridge_length, weight, trucks):
    time = 0
    bridge = deque([0] * bridge_length) # 다리 상태
    trucks = deque(trucks) # 대기 트럭 큐
    current_weight = 0 # 현재 다리 위의 총 무게

    while trucks or current_weight > 0 : # 대기 트럭이 있거나, 대기 트럭이 없다면 다리에서 다 내려갈때까지
        time += 1 # 트럭이 다리를 모두 내려울 때까지 시간이 경과됨

        # 다리에서 맨 앞의 트럭이 내려옴 / 만약 맨 앞에 트럭이 없었다면 아무 일도 일어나지 않음 (-0)
        exited_truck = bridge.popleft()
        current_weight  -= exited_truck

        # 대기 중인 트럭이 다리 위에 올라갈 수 있는가?
        if trucks and current_weight + trucks[0] <=  weight :
            truck = trucks.popleft()
            bridge.append(truck)
            current_weight += truck
        else : # 다리 위에 못올라가면 빈 공간 유지
            bridge.append(0)

    return time

 

다른 사람 풀이 2

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()

 

다른 사람 풀이 3

from collections import deque

def solution(bridge_length, weight, truck_weights):
    bridge = deque(0 for _ in range(bridge_length))
    total_weight = 0
    step = 0
    truck_weights.reverse()

    while truck_weights:
        total_weight -= bridge.popleft()
        if total_weight + truck_weights[-1] > weight:
            bridge.append(0)
        else:
            truck = truck_weights.pop()
            bridge.append(truck)
            total_weight += truck
        step += 1

    step += bridge_length

    return step