저장을 습관화

프로그래머스 LV.0 정수를 나선형으로 배치하기 본문

코딩 테스트/프로그래머스 - 자바스크립트

프로그래머스 LV.0 정수를 나선형으로 배치하기

ctrs 2024. 2. 19. 09:24

프로그래머스 LV.0 정수를 나선형으로 배치하기

https://school.programmers.co.kr/learn/courses/30/lessons/181832

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

 

1. 문제 명

정수를 나선형으로 배치하기


2. 문제 설명

양의 정수 n이 매개변수로 주어집니다. n × n 배열에 1부터 n2 까지 정수를 인덱스 [0][0]부터 시계방향 나선형으로 배치한 이차원 배열을 return 하는 solution 함수를 작성해 주세요.


3. 제한 사항

1 ≤ n ≤ 30


4. 예시

n result
4 [[1, 2, 3, 4], [12, 13, 14, 5], [11, 16, 15, 6], [10, 9, 8, 7]]
5 [[1, 2, 3, 4, 5], [16, 17, 18, 19, 6], [15, 24, 25, 20, 7], [14, 23, 22, 21, 8], [13, 12, 11, 10, 9]]


5. 기본 제공 코드

function solution(n) {
    var answer = [[]];
    return answer;
}


6. 제출한 내 답

const solution = (n) => {
  let answer = [];
  for (i = 0; i < n; i++) {
    answer.push(new Array(n));
  }

  let [x, y] = [0, 0];
  let [infimum, supremum] = [0, n];

  for (number = 1; number <= n ** 2; number++) {
    answer[x][y] = number;
    if (x === infimum && y !== supremum - 1) {
      y += 1;
    } else if (y === supremum - 1 && x < supremum - 1) {
      x += 1;
    } else if (x === supremum - 1 && y > infimum) {
      y -= 1;
    } else if (x === supremum - 1 && y === infimum) {
      supremum -= 1;
      infimum += 1;
      x -= 1;
    } else if (x > infimum && y === infimum - 1) {
      x -= 1;
    }
  }

  return answer;
};

 

6-2. VSC에 작성한 내용

const solution = (n) => {
  let answer = [];
  for (i = 0; i < n; i++) {
    answer.push(new Array(n));
  }

  let [x, y] = [0, 0];
  let [infimum, supremum] = [0, n];

  for (number = 1; number <= n ** 2; number++) {
    // x와 y가 가능한 최저의 수는 infimum, 최대는 supremum
    // 1. y가 supremum까지 커진다.
    // 2. x가 supremum까지 커진다.
    // 3. y가 infimum까지 작아진다.
    // 4. x가 상한선, y가 하한선에 도달했다면 상한선은 1 낮추고, 하한선은 1 올린다.
    // 5. x가 작아진다.
    answer[x][y] = number;
    if (x === infimum && y !== supremum - 1) {
      y += 1;
    } else if (y === supremum - 1 && x < supremum - 1) {
      x += 1;
    } else if (x === supremum - 1 && y > infimum) {
      y -= 1;
    } else if (x === supremum - 1 && y === infimum) {
      supremum -= 1;
      infimum += 1;
      x -= 1;
    } else if (x > infimum && y === infimum - 1) {
      x -= 1;
    }
  }

  return answer;
};

// test
console.log(solution(4));
console.log(solution(5));


7. 특이사항

정말 0 레벨이 맞는지 의문이 들 정도로 굉장히 어려웠고

지금까지 프로그래머스에서 풀었던 것 중 가장 많이 고민했다

조금 더 깔끔하게 작성하고 싶었으나 잘되지 않아 억지로 잡아비틀었다.

 

문제 설명을 노트에 적어가면서보니 일정한 패턴이 있다는 것을 알게되었다.

1. 배열에 요소 삽입은 push 등이 아닌 answer[x] = 숫자로 직접 지정한다.

2. 요소가 들어갈 지점을 answer[x][y]라고 할때, 

x = 0, y = 0으로 시작하여 y가 매개변수 n까지 커진다.([0,0], [0,1], [0,2] ... [0,n])

3. y가 n에 도달했다면 x도 n까지 커진다.([0,n], [1,n], [2,n] ... [n,n])

4. x도 n에 도달했다면 y는 다시 작아진다.([n,n-1], [n,n-2] ... [n,0])

5. 이때, x와 y가 도달할수 있는 가장 큰 수(상한, supremum)은 1이 줄어들고,

가장 작은 수(하한, infimum)은 1 커진다.

결과의 모습이 바깥쪽부터 시계방향으로 점점 안쪽으로 모이는 나선형이기 때문이다.

배열의 요소에 들어갈 수가 커질수록 점점 중앙으로 모이게 될 것이다.

6. x도 점점 작아진다. x가 하한에 도달했다면, 1번 작업부터 반복한다.

요소로 들어갈 수가 n의 제곱이 될때까지이다.

 

여기까지는 알아냈으나 이를 구현해내는데 오래 걸렸고, 결국 풀었다.

 

프로그래머스 기초 문제 끝!