✨ Lv. 2 - 삼각 달팽이
문제 링크 : https://school.programmers.co.kr/learn/courses/30/lessons/68645
정수 n이 매개변수로 주어집니다. 다음 그림과 같이 밑변의 길이와 높이가 n인 삼각형에서 맨 위 꼭짓점부터 반시계 방향으로 달팽이 채우기를 진행한 후, 첫 행부터 마지막 행까지 모두 순서대로 합친 새로운 배열을 return 하도록 solution 함수를 완성해주세요.
우선 n
의 값에 따른 피라미드 형태의 0
으로 값을 초기화한 2차원 배열을 생성합니다. 이후, 방향에 따라 n
층의 피라미드를 이루고 있는 배열 요소의 개수만큼 반복하며 달팽이 채우기를 진행하는 방식으로 풀이하였습니다.
direction === 1
: 다음 행이 없거나, 값이 0이 아닐 경우 돌기direction === 2
: 다음 요소가 없거나, 값이 0이 아닐 경우 돌기direction === 3
: 다음 요소가 0이 아닐 경우 돌기
이후, reduce
와 concat
을 활용하여 하나의 배열로 합쳐 return 하였습니다. 이에 대한 코드는 다음과 같습니다.
function solution(n) {
// 빈 배열 생성
let triangle = Array.from({length : n}, (_, i) => new Array(i + 1).fill(0));
// 현재 index를 저장할 변수와 방향을 저장할 변수, 총 반복할 횟수를 담은 변수를 선언
let idx1 = 0, idx2 = 0, direction = 1, total = 0;
// 총 반복할 횟수를 구하여 저장
triangle.forEach((v) => total += v.length);
// 반복하여 달팽이 채우기를 진행
for(let i = 1; i <= total; i++) {
triangle[idx1][idx2] = i;
if(direction === 1) {
if(!triangle.at(idx1 + 1) || triangle[idx1 + 1][idx2] !== 0) {
idx2++;
direction = 2;
}
else idx1++;
}
else if(direction === 2) {
if(!!triangle[idx1][idx2 + 1] || triangle[idx1][idx2 + 1] !== 0) {
idx1--;
idx2--;
direction = 3;
}
else idx2++;
}
else {
if(triangle[idx1 - 1][idx2 - 1] !== 0) {
idx1++;
direction = 1;
}
else {
idx1--;
idx2--;
}
}
}
// 2차원 배열을 하나의 배열로 합쳐 return
return triangle.reduce((result, v) => result.concat(v), []);
}
상단 코드를 더 단순하고 명확하게 표현한 정답 코드가 있어, 다른 풀이법을 소개합니다. 현재 index를 표현할 idx1
과 idx2
, 현재 들어갈 숫자를 저장할 number
를 선언합니다. 반복하여 달팽이 채우기를 진행한 후, flat
을 이용하여 하나의 배열로 변환하여 return 합니다.
Array.prototype.flat()
flat()
메서드는 모든 하위 배열 요소를 지정한 깊이까지 재귀적으로 이어붙인 새로운 배열을 생성합니다.
이에 대한 코드는 아래와 같습니다.
function solution(n) {
let triangle = Array.from({length : n}, (_, i) => new Array(i + 1).fill(0));
let idx1 = -1, idx2 = 0, number = 0;
for(let i = n; i > 0; i -= 3) {
triangle[++idx1][idx2] = ++number;
for(let j = 0; j < i - 1; j++) triangle[++idx1][idx2] = ++number;
for(let j = 0; j < i - 1; j++) triangle[idx1][++idx2] = ++number;
for(let j = 0; j < i - 2; j++) triangle[--idx1][--idx2] = ++number;
}
return triangle.flat();
}