https://school.programmers.co.kr/learn/courses/30/lessons/42583
< 문제 >
트럭 여러 대가 강을 가로지르는 일차선 다리를 정해진 순으로 건너려 합니다.
다리에는 트럭이 최대 bridge_length대 올라갈 수 있으며,
다리는 weight 이하까지의 무게를 견딜 수 있습니다.
다리에 완전히 오르지 않은 트럭의 무게는 무시합니다.
예를 들어, 트럭 2대가 올라갈 수 있고 무게를 10kg까지 견디는 다리가 있습니다.
무게가 [7, 4, 5, 6]kg인 트럭이 순서대로
최단 시간 안에 다리를 건너려면 다음과 같이 건너야 합니다.
최초의 아이디어
- 일단 큐를 사용해야 한다는 점
- 다리 위의 상태를 변수로 표현하는 것
- 다리 위로 올라간 트럭의 무게를 변수로 표현하는 것
위와 같은 데이터 구조와 변수를 생각해 냈다는 점은 칭찬하지만, 그럼에도 구현상의 논리적 흐름에 구멍이 컸다. 다리 위로 트럭을 올려 시간을 추가하는 것까지 생각해 구현했지만 다리를 지나가고 난 다음의 상태, 다리 위 트럭의 갯수를 고려하지 못했다.
< v1. 코드 구현 흐름 >
- bridge배열이 비어있으면
- 트럭을 추가하고, 1초가 경과된 시간도 추가한다
- 다리가 비어있지 않으면
- 다리 위에 올라간 트럭의 무게와 다리가 지탱할 수 있는 트럭의 무게를 비교해서 다리에 트럭을 추가하거나 이전 트럭을 뺀다.
function solution(bridge_length, weight, truck_weights) { let time = 0; let bridges = []; let bridgeSum = 0; bridges.forEach((item) => (bridgeSum += item)); // while (truck_weights.length > 0) { for (let i = 0; i < truck_weights.length; i++) { if (bridges.length === 0) { // 다리가 비어있으면 bridges.push(truck_weights[i]); time += 1; } else if (bridges.length < bridge_length) { // 다리가 비어있지 않으면 time += 1; if (bridgeSum < weight) { // 다리 무게가 weight보다 작으면 bridges.push(truck_weights[i]); time += 1; } else { // 다리 무게가 weight보다 크면 bridges.shift(); truck_weights.shift(); } } else { time += 1; } } // } return time; }
< 보충해야 할 점 >
- for와 while반복문을 사용했지만 for반복문의 기준이 되는 truck_weight의 길이를 shift()로 줄이고 있기 때문에 명확한 반복문이 되지 않았던 점, while이 자꾸 무한반복 되는 점ㅋㅋㅋㅋㅋ ( 코드 상의 이해가 부족 )
- 데이터로 초기화 해야 하는 값들에 대한 설정이 부족함 ( bridgeSum, 반복문 밖에서 값을 더해주고 있음. 데이터 반영이 잘 안됨 / bridge 빈배열 )
- 모든 트럭이 다리를 지나가는 시간에 대한 값을 정확히 체크하고 있는지의 여부가 불확실함 ( 매 조건문마다 time을 추가해주는데….흠…. )
- 트럭이 다리에 올라간 것과 내려간 부분의 표현이 애매함 ( 올라간 것은 있지만 내려간 것은 없다 )
< v2. 코드 구현 흐름 >
- bridges 다리에 올라갈 수 있는 트럭의 수를 queue로 표현할 수 있도록 트럭의 수만큼 배열로 초기화함.
- 다리에 올라간 트럭과 지나간 트럭을 push와 shift를 사용해 표현함
- 트럭을 추가할 때 weight보다 크다면 0을 넣어서 트럭이 올라오지 않게 설정함
- shift를 통해 bridges의 공간을 빼줌.
- 반복문의 처음부분에 time을 추가해줌. if조건문에 따라 time을 추가했던 부분을 맨위로 올림 ⇒ 모든 행위의 시작에는 1초가 흐르기 때문에.
- while반복문만 사용함. ( truck_lenght가 0이 될 때까지 )
function solution(bridge_length, weight, truck_weights) {
let answer = 0;
**let bridges = Array(bridge_length).fill(0);**
let bridgeSum = 0;
console.log(bridges);
while (truck_weights.length > 0 || bridges.length > 0) {
answer++;
// 1. 다리를 건넌 트럭 제거
const truck = bridges.shift();
bridgeSum -= truck; // 다리 위 무게에서 제거
// 2. 새로운 트럭 추가 가능 여부 확인
if (truck_weights.length > 0) {
if (bridgeSum + truck_weights[0] <= weight) {
const newTruck = truck_weights.shift(); // 대기 트럭을 다리 위로 올림
bridges.push(newTruck);
bridgeSum += newTruck; // 다리 위 무게 갱신
} else {
**bridges.push(0); // 트럭을 추가할 수 없으면 빈 공간 유지**
}
}
}
return answer;
}
console.log(solution(2, 10, [7, 4, 5, 6])); // 8
// console.log(solution(100, 100, [10])); // 101
// console.log(solution(100, 100, [10, 10, 10, 10, 10, 10, 10, 10, 10, 10])); // 110
전체적으로 논리적인 흐름을 잘 구성하는 게 먼저임을 오늘도 깨닫는다!! 헤헷,
'개발공부_Blog > Algorithm' 카테고리의 다른 글
완주하지 못한 선수 (0) | 2024.11.29 |
---|---|
JadenCase 문자열 만들기 (1) | 2024.11.28 |
프로그래머스-주식가격 (1) | 2024.11.18 |
프로그래머스 - 프로세스 (0) | 2024.11.17 |
알고리즘과 자료구조 그리고 시간복잡도 사이의 관계 (0) | 2024.10.22 |
댓글