[코딩테스트] - 프로그래머스 택배 상자 꺼내기

Kwon Donghyun·2025년 3월 12일
0

코딩테스트

목록 보기
2/2

프로그래머스 코드챌린지 2차 예선 - Lv. 1 택배 상자 꺼내기

문제

1 ~ n 번호가 있는 택배 상자
왼쪽에서 오른쪽으로 가면서 1번부터 순서대로 1개씩 놓고 w개가 놓였다면 위에 오른쪽부터 왼쪽으로 가면서 상자를 한 개씩 놓는다.

총 n개의 상자를 모두 쌓았을 때 꺼내려는 상자 번호 num을 꺼내려면 위에 상자 포함해서 몇 개의 상자를 꺼내야하는지 찾는 문제

고민

  1. 2차원 배열에 번호 세팅
  2. 수학적으로 로직 계산

나는 2번 수학적으로 계산해서 푸는 방법을 선택했고 이 결과는 2일이라는 시간 동안 이 문제를 풀게되었다...

수학적 로직 계산 과정

  • height에 따라 pos를 계산한 뒤 count 계산

    • 이 과정에서 height가 짝수일 때와 홀수일 때 달라지는 경우에 집중했다.
     int height = 1;
     int pos;
     
     if (height % 2 == 0) pos = (w - num % w) % w + 1;
     else pos = num % w;
     
     int count = 0;
     
     while (true) {
     	int 홀수 = (w * 2) * (height - 1) + pos;
     	int 짝수 = (w * 2) * height - pos;
    
     	if (홀수 >= num) count++;
     	if (홀수 > n) break;
    
     	if (짝수 >= num) count++;
     	if (짝수 > n) break;
    
     	height++;
     }

문제점

  • height를 2층마다 1개의 height로 묶어서 처리하는걸 생각했었다.
  • pos 계산할 때 각각 홀수, 짝수일 때 pos가 0으로 바뀔 때가 존재하고 홀수일 때와 짝수일 때 pos가 달라야했다.

height를 계산할 때 2개를 묶어서 계산하면서 pos를 찾아가는데 이 방법의 문제는 내가 찾는 num 값이 홀수에 있을지 짝수에 있을지 모르는 상태에서 2개씩 묶어 처리하면서 이상하게 꼬였던 것 같다.

해결

int level = (num - 1) / w + 1;
int pos = (num - 1) % w + 1;
int count = 0;

while (true) {
	int value = w * (level - 1) + pos;
    
    if (n >= value) count++;
    if (n < value) break;
    
    level++;
    pos = w - (pos - 1);
}

return count;
  • num의 level을 찾아 해당 pos의 위치를 찾는 계산식을 찾았다.

    num에 - 1을 하면서 1 ~ w 범위를 찾을 수 있었다.
    level : (num - 1) / w + 1;
    pos : (num - 1) % w + 1;

  • value로 level + pos에 해당하는 값을 찾아 비교 후 count를 더해주고 value가 n을 넘어가면 반복문을 종료시켰다.
  • level을 증가시키고 pos를 반대로 변경해줬다.
    • w : 6 (1 ~ 6) 일 때 pos : 2 -> 5 or 5 -> 2
  • level을 높이면서 탐색을 한 뒤 value가 n을 넘길 때까지 count를 증가시켜 원하는 값을 찾았다.

다른 사람 풀이

Hyunuk17 풀이

int cnt = 0;
while (num <= n) {
	num += (w - ((num - 1) % w) - 1) * 2 + 1;
    cnt++;
}

return cnt;

num의 height나 level을 생각하지 않고 더해지는 값이 어떻게 반복되는지 생각하면 굉장히 쉽게 풀릴 수 있었다.

  • 위치 찾는 부분 : (num - 1) % w -> 0 ~ w - 1
  • 다음 값 찾는 부분 : (w - 위치 찾는 부분 - 1) * 2 + 1;
    • 현재 위치가 1인 경우에 현재값 + (w - 0 - 1) * 2 + 1 결과가 다음 값인걸 알 수 있다.

회고

이 문제를 2일 동안 붙잡았던 이유는 Lv. 1 문제를 수학적으로 풀 수 있을 것 같은데 어떻게 생각해야될지 방황을 많이 했던 것 같다.
굉장히 쉬운 문제인데 어떻게 생각하냐에 따라 로직이 달라질 수 있기 때문에 이번 기회에 부족한 부분을 파악하기 위해 시간을 쓰더라도 부딪쳐봐야겠다 생각했다.

이런 경험들이 쌓여 문제를 어떻게 풀어야할지 고민하는 시간을 줄여줄 것이라 생각한다.

코딩테스트는 문제를 많이 접하면서 다양하게 생각해보고 점점 최적의 로직을 생각하는 연습을 하는 것이라 생각한다.

조급하기보다는 많이 풀어보고 다양한 접근 방법을 익히는 연습하기

0개의 댓글