본문 바로가기

Algorithm/Stack, Queue

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

 예전 학부 3학년때 운영체제 과제로 CPU스케쥴링 프로그램을 짜는 과제가 있었습니다. 그 당시 상당히 어려웠던 걸로 기억하는데  당시 시간을 계산하면서 RR, FCFS, SJF 등을 구현 했던걸로 기억 하는데 당시 썻던 방법이 머리 속에 많이 남아 있어서 인지 모르겠지만 이 문제를 보고 풀이 계획을 머리 속에 그릴때 과제의 RR방법을 바탕으로 구현하면 될 것이라 생각하고 진행하였습니다. 다른 방법으로도 풀수 있는 방법은 많겠지만 그 당시 기억을 바탕으로는 가장 빠르게 풀 수 있는 방법은 밑에 게시한 소스라 생각하고 진행 하였던걸로 기억합니다. 주석을 바탕으로 최대한 자세히 써보려고 했는데 이 글을 보시는 모든 분께 도움이 되었으면 합니다.

 

package SolutionCOM.com.Algorism;

import java.util.LinkedList;
import java.util.Queue;

class Solution {
    
	public static int solution(int bridge_length, int weight, int[] truck_weights) {
		int time = 0;
		//아직 지나가지 않은 트럭들 담을 큐를 생성 
		Queue<int[]> waiting = new LinkedList<>();
		//지나가버린 트럭을 담을 큐생성 
		Queue<int[]> fin = new LinkedList<>();
		//아직 다리를 건너고 있는 트럭정보를 담을 큐생성 
		Queue<int[]> ing = new LinkedList<>();

		for (int i = 0; i < truck_weights.length; i++) {
        //배열을 생성하고 [0]인덱스는 트럭의 무게를 
        //[1]인덱스는 다리위에서 건너는 시간을 계산하기 위한 시간데이터를 저장 
			waiting.add(new int[] { truck_weights[i], 0 });

		}
		
		int allow_weight = 0;
		while (true) {
          //문제를 살펴보면 0초에는 아무런 일도 발생하지 않는다. 
          //time을 증가시켜주자 아니면 초기화를 1로 해도된다.
			time++;
            // waiting Queue와 트럭의 무게를 최대로 견딜 수 있는 값의 허용범위를 살피고 가능하다면
            // ing큐에 입력한다.
			if (!waiting.isEmpty() && allow_weight + waiting.peek()[0] <= weight) {
				int[] new_car = waiting.poll();
				int car_weight = new_car[0];
                //allow_weight의 값을 변경시켜주고 다리를 완전히 건너는 시간을 계산하여 
                //배열에 추가한 뒤 큐에 입력한다.
				allow_weight+=car_weight;
				int car_time = time + bridge_length-1;
				ing.add(new int[] { car_weight, car_time });

			}
            //현재 다리를 건너고 있는 트럭이 있는지 확인 후 탈출하는 시간과 
            //현재시간이 일치한다면 fin Queue로 뺴준다.
			if (!ing.isEmpty() && time == ing.peek()[1]) {
				int[] tmp_next = ing.poll();
				allow_weight-=tmp_next[0];
				fin.add(tmp_next);
			}
			//더 이상 진행할 작업과 지나고 있는 트럭이 없다면 종료한다.
			if (waiting.isEmpty() && ing.isEmpty()) {
				break;
			}
		}
	    int answer = time+1;
		return answer;
	}
}