[프로그래머스 2레벨] n^2 배열 자르기

이민선(Jasmine)·2023년 2월 13일
1

문제

정수 n, left, right가 주어집니다. 다음 과정을 거쳐서 1차원 배열을 만들고자 합니다.

n행 n열 크기의 비어있는 2차원 배열을 만듭니다.
i = 1, 2, 3, ..., n에 대해서, 다음 과정을 반복합니다.
1행 1열부터 i행 i열까지의 영역 내의 모든 빈 칸을 숫자 i로 채웁니다.
1행, 2행, ..., n행을 잘라내어 모두 이어붙인 새로운 1차원 배열을 만듭니다.
새로운 1차원 배열을 arr이라 할 때, arr[left], arr[left+1], ..., arr[right]만 남기고 나머지는 지웁니다.
정수 n, left, right가 매개변수로 주어집니다. 주어진 과정대로 만들어진 1차원 배열을 return 하도록 solution 함수를 완성해주세요.

제한사항
1 ≤ n ≤ 107
0 ≤ left ≤ right < n2
right - left < 105
입출력 예

n	left	right	result
3    2   	 5  	[3,2,2,3]
4	 7  	 14 	[4,3,3,3,4,4,4,4]

입출력 예 설명
입출력 예 #1

다음 애니메이션은 주어진 과정대로 1차원 배열을 만드는 과정을 나타낸 것입니다.



나의 코드

function solution(n, left, right) {
    const totalEls = right - left + 1;
    let [i, j] = [parseInt(left / n), left % n];
    
    let arr = [];
    while(arr.length < totalEls){
        arr.push(i >= j ? i + 1 : j + 1);
        
        if(j === n - 1){
           j = 0;
           i++;
        } else j++;
    }
     return arr;
}

코드를 최대한 간결하게 만드는 데에 집중했다.
사실 이 문제를 처음 봤을 때 순진한 코린이인 나는 실제로 저 애니메이션에 나오는 배열을 만든 다음 slice로 잘라서 제출했다.
순진한 코린이1 : 옹 ? 어렵지 않은데??
그리고 당연히 실패 ㅋㅋㅋㅋㅋㅋㅋ

제한사항
1 ≤ n ≤ 107
0 ≤ left ≤ right < n2
right - left < 105

무시무시한 제한사항이 걸려있는데 언제 배열을 다 만들고 앉아있니...
애초부터 잘라져있는 배열을 만들어야 한다!
arr에 값을 하나씩 push해 줄 것이다.
totalEls는 while문을 몇번 돌릴지 정하는 것이다. left ~ right 사이의 숫자 개수 + 1이 될 것이다.
그리고 시작 행과 열을 [i, j]로 선언해놓고 반복문을 한 번 돌릴 때마다 열번호를 하나씩 증가시켜준다. 열번호가 n - 1이 되면 행번호도 +1 해주고, 열번호는 0으로 만들어준다.
반복문을 한번 돌릴 때마다 arr에 push해주어야 하는 값은 i와 j중 큰 값 + 1이다.
끝!
이렇게 했더니 통과가 되었다. 요즘 거의 다 1점 받다가 오랜만에 6점 받았다 !!! (감격)
(생각해보니 앞으로 블로그에 점수도 같이 포스팅해야겠다. 내 코드를 평가해줄 수 있는 유일한 척도는 프로그래머스에서 주는 점수잖아..)

아니 그런데 ㅋㅋㅋㅋ 내 코드도 꽤나 줄이고 줄여 간결하다고 생각했는데 훠~~얼씬 더 간결하게 풀 수 있었다.

다른 코드

function solution(n, left, right) {
    var answer = [];

    for (let i = left; i <= right; i++) {
        answer.push(Math.max(i % n, parseInt(i / n)) + 1)
    }

    return answer;
}

응? 나 같은 문제 푼 것 맞니?
ㅋㅋㅋㅋㅋㅋㅋㅋㅋ

이 코드에서 i % n은 열 번호를 나타낸다.
특정 index를 n으로 나눈 나머지가 같으면 전부 같은 열에 있다.
예를 들어 3번째 열이라면, 인덱스가 2부터 시작하므로
2 % 3 = 5 % 3 = 8 % 3 = ... = 2

그리고 parseInt(i/n)은 행번호를 나타낸다.
예를 들어 첫번째 행이라면
parseInt(0 / 3) = parseInt(1 / 3) = parseInt(2 / 3) = 0
두번째 행이라면
parseInt(3 / 3) = parseInt(4 / 3) = parseInt(5 / 3) = 1
.
.
즉 행번호와 열번호 중 큰 숫자에 1을 더한 값을 배열에 push하는 것이다.
1을 더하는 이유는 index가 아닌 '몇 번째'인지를 반환해야하기 때문이다.
생각보다 간단한 논리이지만 막상 현란한 애니메이션을 보니 전혀 떠오르지 않았던 것 같다. ㅋㅋㅋㅋㅋㅋ

여하튼 정사각형 2차원 배열이 있을 때
같은 열에 있는 모든 원소의 index를 정사각형 변의 크기로 나누면 나머지가 모두 같고,
같은 행에 있는 모든 원소의 index를 정사각형 변의 크기로 나누어 내림하면 모두 같은 값을 갖는다는 논리는 앞으로도 종종 써먹을 것 같은 느낌적인 느낌이다.

이제 자러갑니다. 짜이찌앤~~~

profile
기록에 진심인 개발자 🌿

0개의 댓글