다리를 지나는 트럭

출처 = 프로그래머스

문제

일차선인 다리에 트럭 여러대가 지나가는데 걸리는 총 시간을 구해라.
단 다리에 올라간 트럭의 무게가 다리의 최대하중을 넘어선 안된다.

고민

전에 풀었던 문제인데 코드를 다시보니 알아보기가 너무 힘들었다.
그래서 최근에 다시 알아보기 쉽게 코드를 다시 짜보았다.
트럭과 다리를 객체로 만들고 각각에 필요한 기능들을 메서드로 넣고나니
훨씬 알아보기가 편해졌다.

방법

대기중은 트럭과 다리에 올라간 트럭은 큐를 사용해서 만들고
다리에 올라간 트럭은 다리의 멤버변수로 넣는다.

다리에 트럭이 올라갈 수 있는지 확인한다.
올라갈 수 있으면 다리트럭큐에 넣고 시간에 1을 더한다.
올라갈 수 없으면 첫번째 트럭이 내려올때까지 시간을 더한다
트럭이 도착했으면 다리트럭큐에서 빼준다.

위의 과정을 다리에 올라가길 기다리는 트럭이 없을때까지 반복한다.

마지막 트럭이 다리에 올라가면 트럭이 도착할 때까지 걸리는 시간을 더한다.

코드

[다리를 지나가보자] []
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
public class Solution {
//트럭클래스
public class Truck{
int weight;
int move;

public Truck(int weight) {
this.weight = weight;
}

public void move() {
this.move++;
}

public int getMove() {
return this.move;
};

public int getWeight() {
return this.weight;
};

}

//다리클래스
public class Bridge{
int length;
int weight;
Queue<Truck> onTruckQueue = new LinkedList<>();

public Bridge(int length, int weight) {
this.length = length;
this.weight = weight;
}

public boolean isOnPossible(int weight) {
for(Truck t : onTruckQueue) {
weight += t.weight;
}
return weight <= this.weight;
}

public void truckIn(Truck t) {
onTruckQueue.add(t);
}

public void truckOut() {
onTruckQueue.poll();
}

public boolean isArrived() {
return onTruckQueue.peek().getMove() >= this.length;
}

public void allMove() {
for(Truck t : onTruckQueue) {
t.move();
}
}

public int moveUntilTruckArrive(int answer) {
for(int i = 0; i < this.length - this.onTruckQueue.peek().getMove(); i++) {
this.allMove();
answer++;
}
return answer;
}

public int moveLastTruck(int answer) {
return answer += this.length;
}

}

public int solution(int bridge_length, int weight, int[] truck_weights) {
int answer = 0;

//객체 생성하고 대기트럭큐 생성후 큐에 트럭을 넣어줌
Bridge bridge = new Bridge(bridge_length,weight);
Queue<Truck> waitTrucks = new LinkedList<>();
for (int tWeight : truck_weights) {
waitTrucks.add(new Truck(tWeight));
}

//대기트럭이 없을때까지 반복
while(waitTrucks.size() != 0) {
//다리에 올릴 수 있는지 확인하고 가능하면 트럭을 넣고 시간에 1초 더해줌
if(bridge.isOnPossible(waitTrucks.peek().getWeight())) {
bridge.truckIn(waitTrucks.poll());
bridge.allMove();
answer++;
}
//올릴 수 없으면 다리의 첫번째 트럭이 도착할때까지 시간을 더해줌
else answer = bridge.moveUntilTruckArrive(answer);

//트럭이 도착했으면 다리트럭큐에서 빼줌
if(bridge.isArrived()) bridge.truckOut();
}

//다리의 마지막 트럭이 도착할때까지 시간을 더함
answer = bridge.moveLastTruck(answer);

return answer;

}

}

결과

전에 풀었던 코드보다 훨씬 알아보기도 편하고
걸리던 시간도 단축됐다.
가끔 과거 코드를 바꿔보는 것도 도움이 되는 것 같다.

끝!

공유하기