카테고리 없음
[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