[프로그래머스] 택배 상자 꺼내기 JavaScript

·2025년 3월 12일

문제

1 ~ n의 번호가 있는 택배 상자가 창고에 있습니다. 당신은 택배 상자들을 다음과 같이 정리했습니다.

왼쪽에서 오른쪽으로 가면서 1번 상자부터 번호 순서대로 택배 상자를 한 개씩 놓습니다. 가로로 택배 상자를 w개 놓았다면 이번에는 오른쪽에서 왼쪽으로 가면서 그 위층에 택배 상자를 한 개씩 놓습니다. 그 층에 상자를 w개 놓아 가장 왼쪽으로 돌아왔다면 또다시 왼쪽에서 오른쪽으로 가면서 그 위층에 상자를 놓습니다. 이러한 방식으로 n개의 택배 상자를 모두 놓을 때까지 한 층에 w개씩 상자를 쌓습니다.

위 그림은 w = 6일 때 택배 상자 22개를 쌓은 예시입니다.
다음 날 손님은 자신의 택배를 찾으러 창고에 왔습니다. 당신은 손님이 자신의 택배 상자 번호를 말하면 해당 택배 상자를 꺼내줍니다. 택배 상자 A를 꺼내려면 먼저 A 위에 있는 다른 모든 상자를 꺼내야 A를 꺼낼 수 있습니다. 예를 들어, 위 그림에서 8번 상자를 꺼내려면 먼저 20번, 17번 상자를 꺼내야 합니다.

당신은 꺼내려는 상자 번호가 주어졌을 때, 꺼내려는 상자를 포함해 총 몇 개의 택배 상자를 꺼내야 하는지 알고 싶습니다.

창고에 있는 택배 상자의 개수를 나타내는 정수 n, 가로로 놓는 상자의 개수를 나타내는 정수 w와 꺼내려는 택배 상자의 번호를 나타내는 정수 num이 매개변수로 주어집니다. 이때, 꺼내야 하는 상자의 총개수를 return 하도록 solution 함수를 완성해 주세요.

제한 사항

2 ≤ n ≤ 100
1 ≤ w ≤ 10
1 ≤ num ≤ n

예제 입력

n : 22
w : 6
num : 8

예제 출력

3

내가 했던 풀이 방법

  1. 범위가 크지 않으므로 box를 직접 만들어도 괜찮다. 1부터 a층까지 택배를 쌓을 것이므로 반복문을 이용한다. a층은 num에서 w를 나눈 수를 올림처리해주면 된다. 문제와 같이 한 층에 6개씩 22개의 상자를 쌓으면 4층이 필요하다.
  2. 각 층에 담긴 상자를 담을 line 배열을 선언하고 w개만큼 담아준다. 이때 box의 번호를 체크하기 위해 idx를 1부터 증가시켜준다. 만약, n보다 커지면 w개를 담지 못했어도 중단한다. 그리고 도중 idx가 num이 된다면 문제에서 찾고 있는 택배 상자이므로 해당 상자의 위치를 numIndex에 담아준다. 이때, 짝수층인 경우에는 순서가 reverse 되어 있으므로 짝수층일 때는 j가 아닌 w-j-1을 해주어야 한다.
  3. 2번에서 언급하였듯이 짝수층일 땐 순서가 reverse 되어 있으므로 만약 짝수층일 경우 reverse하여 box에 넣고 홀수층일 경우에는 그냥 넣어준다. 이때, line 배열은 마지막 층일 경우 w개가 채워지지 못했을 수도 있다. 이때 그냥 넣어주면 다른 층과 헷갈릴 수 있으므로 line을 push하기 전 length가 w가 될 때까지 null을 push해주어 크기를 맞춰준다.
  4. 이를 모두 진행하면 box에는 문제대로 택배 상자가 쌓이고 numIndex에는 찾으려는 택배의 위치가 담기게 된다. 전체 box의 길이에서 그 택배의 y위치를 빼면 빼내야 할 택배 상자가 몇개인지 알 수 있다. 하지만, 문제에서 요구한 상자까지 빼는 횟수에 포함되므로 +1을 해주어야 한다. 계산한 뒤 answer에는 빼내야 하는 상자의 갯수가 담겨있다. 하지만, 이때 마지막 층에는 null이 포함되어 있을 수도 있다. 그러므로 마지막 층에서 찾으려는 택배의 x위치에 null이 들어있다면 answer를 1 빼주어야 한다.

코드

function solution(n, w, num) {
    var answer = 0;
    let box = [];
    
    let idx = 1;
    let numIndex = [0, 0];
    for(let i=1; i<=Math.ceil(n/w); i++) {
        let line = [];
        for(let j=0; j<w; j++) {
            if(idx>n) break;
            if(idx===num) numIndex = [i, i%2===0?w-j-1:j];
            line.push(idx++);
        }
        
        while (line.length < w) {
            line.push(null);
        }
        
        if(i%2===0) box.push([...line.reverse()]);
        else box.push([...line]);
    }

    answer = box.length-numIndex[0]+1;
    if(!box[box.length-1][numIndex[1]]) answer--;
    return answer;
}

회고

Lv.1 치고는 조~금 어려운 편이지 않나 싶은데 막상 풀고나니까 더 간단하게 풀 수 있을 것 같긴하다. 직접 구현하지 않고 수학적인 부분으로도 충분히 계산 가능할 듯.

profile
Frontend🍓

0개의 댓글