코드 풀이. [Queue] 박스 포장

배상건·2022년 3월 4일
0

TIL

목록 보기
5/15

뒷사람이 포장을 전부 끝냈어도 앞사람이 끝내지 못하면, 퇴장할 수 없으며,
앞 사람이 포장을 끝내면, 포장을 마친 뒷사람들과 함께 한 번에 나가게 되는 진열대가 있다.

문제: 이때, 최대 몇 명이 한번에 나가는지 알 수 있도록 함수를 구현하시오.

주의 사항 : 포장을 전부 끝낸 사람이 있더라도, 앞사람이 포장을 끝내지 않으면 나갈 수 없다

1. 접근하기

  • 선형 구조로써 선형 탐색을 진행한다.
  • FIFO
  • Queue는 while 반복문과 함께 쌍을 이룰때가 많다.

2. 코드

function paveBox(boxes) {
  	// 1. 퇴장 인원 수를 요소로 갖는 배열 answer 선언
	// 2. 배열 boxes의 모든 요소를 순회하면서, 퇴장 인원수가 기록된 뒤,
    //    가장 많은 인원이 퇴장한 요소가 최대 퇴장 인원이 된다.
    let answer = [];
    
    // 3. 모든 인원이 포장을 마치고, 진열대가 빌 때까지 반복해야하므로,
  	//    배열 boxes의 모든 박스가 포장을 마치고 퇴장 할때까지 반복한다.
    while(boxes.length > 0){
      	// 4. 각 박스에서 확인할 것은 맨 앞의 박스의 포장 개수보다 
      	//	  많은 손님이 있는지 반복해서 확인한다. 
        let finishIndex = boxes.findIndex(fn => boxes[0] < fn);
		// 5. 만약, 첫번재 손님의 포장할 박스가 가장 많다면,
      	// 5.1. 첫번째 손님이 박스 포장을 마친 뒤 모든 손님이 나갈 수 있으므로
        //      배열 answer에 모든 손님의 인원수를 기록한다.
        // 5.2. 첫번째 손님과 함께 모든 손님이 진열대를 빠져 나갔으므로,
        //      배열 boxes는 빈 상태가 된다.
        if(finishIndex === -1){
            answer.push(boxes.length);
            boxes.splice(0, boxes.length);
        // 6. 만약, 첫번째 손님의 박스보다 많은 박스를 포장 중인 손님이 있다면,
      	// 6.1. 그 앞 손님까지 첫번째 손님과 퇴장하게 되므로,
        //	    배열 answer에 퇴장한 인원수록 요소로 추가한다.
        // 6.2. 첫번째 손님부터 n번째 손님까지 퇴장 했으므로,
        //	    그만큼 배열에서 뺀다.
        } else {
            answer.push(finishIndex);
            boxes.splice(0, finishIndex);
        }
    }

    // 결과물을 반환합니다.
    return Math.max(...answer);
}

3. 수도코드

  1. 박스포장대는 5명이 동시에 포장할 수 있으나, 0번째 손님이 퇴장해야만, 뒷 손님도 나갈 수 있는 환경이다.

  2. 앞 손님이 포장을 마치고 퇴장할 때, 함께 퇴장하는 손님의 수를 기록하는 변수 answer을 선언한다.

  3. 박스포장대가 모두 빌 때까지 0번째 손님보다 많은 박스를 포장하는 손님을 탐색한다.(반 복)

  4. 만약, 0번째 손님보다 박스가 많은 손님이 없다면,

    4.1. 모든 손님이 0번째 손님과 함께 나가므로, 배열 answer에 4명을 기록한다.
    4.2. 모든 손님이 퇴장했으므로, 박스포장대는 비어있는 상태가 된다.

  5. 만약, 0번째 손님보다 박스가 많은 손님이 있다면(),

    5.1. 배열 answer에 해당 손님 앞까지 인원수 n을 전달한다.

    5.2. 박스포장대는 n명이 퇴장했으므로, 남은 손님으로 리셋된다.

  6. 퇴장하지 않은 박스포장대가 있다면, 위 작업을 반복한다.

4. 어려웠던 것은 무엇인가

  1. Queue 자료 구조를 충분히 이해하지 못했다.
    Queue 자료 구조를 적용하여 방법을 찾는 문제였기 때문에,
    FIFO만 생각하고, dequeue가 적용되 었을 때, 남아있는 자료들로 다시 dequeue를 실행할 경우의 수를 고려하지않았다.
  2. dequeue를 실행하기 위한 조건을 어떻게 해야할지 갈피를 잡지 못했다.
    1시간 이상 고민했지만, 어떤 조건으로 반목문을 실행해야할지, 그리고, 최댓값을 어떻게 구해야할지 갈피를 전혀 잡지 못했다.
    결국, 레퍼런스 코드를 보기로 했고, 이를 진지하게 해석하는 시간을 가졌다.
    먼저, 배열 answer의 목적은 반복문으로 '동시 퇴장 가능 인원'을 요소로 갖는 배열로써, 포장해야하는 박스가 담긴 배열 boxes의 모든 요소를 반복 조건에 맞게 확인한 뒤 완성되는 배열이었다.
    위와 같은 방법으로 배열 answer을 완선시키는 것이 whil 반복문의 목적이며,
    완성된 배열 answer의 최댓값이 문제에서 얻고자하는 답인,
    '최대 동시 퇴장 가능 인원'을 구할 수 있게 된다.

5. 문제를 해결하기 위한 몸부림

  1. 개발자 도구에서 레퍼런스 코드를 실행해보았다.
    지금은 너무 당연한 개념이지만, 첫번째 요소보다 큰 요소가 없을 경우,
    첫번째 요소와 함께 모든 요소가 동시에 퇴장하게 된다. 따라서,
    배열 answer은 배열 boxes의 길이를 담게 된다.
    그러나 이러한, 변수의 목적, 경우의 수를 이해하지 못했기 때문에,
    개발자 도구로 실행하여, 해당 경우에 어떤 변화가 일어나는지 직접 눈으로 확인했다.

    추가로, 디버깅으로 확인하는 방법이 더 수월하지만, 아직 디버깅에 익숙치 않아서 길을 돌아서 이해를 하게 되었다. 주말 동안, 디버깅을 연습하도록 하자.
  2. 직접 그리면서 이해해보았다.
profile
목표 지향을 위해 협업하는 개발자

0개의 댓글