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

nRecode·2021년 3월 22일
0

Algorithm

목록 보기
46/48

문제

트럭 여러 대가 강을 가로지르는 일 차선 다리를 정해진 순으로 건너려 합니다. 모든 트럭이 다리를 건너려면 최소 몇 초가 걸리는지 알아내야 합니다. 트럭은 1초에 1만큼 움직이며, 다리 길이는 bridge_length이고 다리는 무게 weight까지 견딥니다.
※ 트럭이 다리에 완전히 오르지 않은 경우, 이 트럭의 무게는 고려하지 않습니다.

예를 들어, 길이가 2이고 10kg 무게를 견디는 다리가 있습니다. 무게가 [7, 4, 5, 6]kg인 트럭이 순서대로 최단 시간 안에 다리를 건너려면 다음과 같이 건너야 합니다.

경과 시간다리를 지난 트럭다리를 건너는 트럭대기 트럭
0[][][7,4,5,6]
1~2[][7][4,5,6]
3[7][4][5,6]
4[7][4,5][6]
5[7,4][5][6]
6~7[7,4,5][6][]
8[7,4,5,6][][]

따라서, 모든 트럭이 다리를 지나려면 최소 8초가 걸립니다.

solution 함수의 매개변수로 다리 길이 bridge_length, 다리가 견딜 수 있는 무게 weight, 트럭별 무게 truck_weights가 주어집니다. 이때 모든 트럭이 다리를 건너려면 최소 몇 초가 걸리는지 return 하도록 solution 함수를 완성하세요.

입출력 예

bridge_lengthweighttruck_weightsreturn
210[7,4,5,6]8
100100[10]101
100100[10,10,10,10,10,10,10,10,10,10]110

접근

truck_weights의 길이가 총 트럭의 댓수이며 배열로 input 됩니다. 문제를 통해 파악할 수 있는 조건은 다리위의 트럭의 수가 bridge_length를 넘겨서는 안되고, 다리위 위의 트럭들의 무게의 합이 weight를 넘겨서는 안됩니다.

문제를 풀어가는 방향은, 반복문을 사용하는 것 입니다.

  1. 마지막으로 return해야한는 값은 걸리는 초(시간)입니다. 따라서 return할 초(시간)역시 선언합니다.

  2. 현재 다리를 지나고 있는 트럭을 알려줄 array 역시 선언합니다. 트럭은 선입 선출이므로 큐의 개념을 생각하면 좋습니다. array의 요소로는 현재 다리를 지나고 있는 트럭의 무게와 남은 시간의 데이터를 갖고있는 객체입니다.
    ex)

let onBridge = [{ truck_weight : truck_weights.shift(), time: bridge_length - 1 }];
  1. while문을 사용합니다. 주어진 트럭의 수 만큼 트럭이 모두 다리를 건넌다면 로직을 끝내도 된다는 의미이므로 반복의 조건은 truck_weights.length건넌 트럭의 수를 카운트한 값이 같지 않다면 반복문이 돌아갑니다.

    위 반복문 안에서는 두가지 로직이 돌아갑니다.

    • 첫번째는 다리를 다 건넜는지 확인하는 작업입니다. onBrige의 0번째 인덱스의 다리를 건너는데 남은 시간이 0인 트럭이 있다면 onBrige의 맨앞에서 pop하고 건넌 트럭의 수를 +1 해줍니다.

    • 두번째는 1초 증가 로직입니다. 소요된 초(시간)을 하나 증가시키고, 현재 다리 위에 있는 트럭의 남은시간을 1씩 감소 시킵니다. 다음 현재 다리에 있는 트럭과 다음 진입할 트럭의 무게의 합을 확인합니다. 또 다리의 길이를 확인합니다.이 두가지 조건을 확인하여 다음 트럭이 다리에 올라갈 수 있다면 진입시킵니다.

풀이

function solution(bridge_length, weight, truck_weights) {
    // truck_weights의 길이가 총 트럭의 댓수이며 배열로 input 
    // 조건
    // 다리위의 트럭의 수가 bridge_length를 넘겨서는 X
    // 다리위 위의 트럭들의 무게의 합이 weight를 넘겨서는 X
    // 반복문을 사용하여 cnt를 올리고 다리를 건너는 트럭이 더이상 없을 때 return 
    
    // 다리를 건너기 전 트럭 수
    let beforecross = truck_weights.length;
    // 다리를 다 건넌 트럭
    let aftercross = 0;
    
    var second = 1;
    let onBridge = [{ truck_weight : truck_weights.shift(), time: bridge_length - 1 }];
    
    while(beforecross !== aftercross){
        //console.log(second, onBridge)
        if(onBridge[0].time === 0){
            onBridge.shift();
            aftercross++;
        }
        
        // 1초 증가로직
        second++;
        // 현재 다리에 있는 모든 트럭의 시간을 1초씩 줄여준다.
        let curWeight = 0;
        onBridge.forEach(val =>{
            curWeight += val.truck_weight;
            val.time--;
        })
        
        // 다음 현재 다리에 있는 트럭과 다음 진입할 트럭의 무게의 합과 다리의 길이를 확인한 후 
        // 다리에 올라갈 수 있는 지 확인 
        if(onBridge.length < bridge_length && curWeight + truck_weights[0] <= weight){
            onBridge.push({ truck_weight : truck_weights.shift(), time: bridge_length - 1 });
        }
        
    }
    return second;
}
profile
안정성, 확장성 있는 서버를 구축하고 가꾸는 개발자를 목표로 공부하고 있습니다. 🤔🤔🤔🤔 부족하기에 맞지 않는 내용이 있을 수 있습니다. 가감없이 피드백 해주시면 정말 감사하겠습니다..🙏

0개의 댓글