https://programmers.co.kr/learn/courses/30/lessons/68645
정수 n이 매개변수로 주어집니다. 다음 그림과 같이 밑변의 길이와 높이가 n인 삼각형에서 맨 위 꼭짓점부터 반시계 방향으로 달팽이 채우기를 진행한 후, 첫 행부터 마지막 행까지 모두 순서대로 합친 새로운 배열을 return 하도록 solution 함수를 완성해주세요.
function solution(n) {
var answer = Array.from(new Array(n), (_, i) => new Array(i+1));
const totalNum = n*(n+1)/2;
let sideNum = n;
const direction = [[1, 0], [0, 1], [-1, -1]];
let curDirection = 0;
let x =0;
let y =0;
let nx = 0;
let ny = 0;
for (let number =1; number <= totalNum ; number++) {
answer[x][y] = number;
nx = x + direction[curDirection][0];
ny = y + direction[curDirection][1];
if (number < totalNum && (nx === n || ny === n || !!answer[nx][ny])) {
curDirection = (curDirection + 1) % 3;
number--;
} else {
x = nx;
y = ny;
}
}
answer = answer.reduce((acc,curr) => {
return [...acc, ...curr];
}, '');
return answer;
}
처음 문제를 접했을 때 꽤 당황스러웠다.
처음에 생각한 방법은 n=6
이면 처음 맨 바깥은 5개씩 세 변을 지나고 그 다음 단계에서는 5-3으로 2개씩 세 변을 지나고 이런 식으로 각 이번 -3을 한 만큼을 다음 단계에서 각 변에 적는 것이었다. 그런데 이렇게 하면 처음에 n=4
일 때 첫 단계에서 3개씩 적고 -3을 하면 0이 되는데 실제로는 하나를 적어야 하기 때문에 예외 상황이 나왔다.
그래서 다음 생각한 방법은 일단 방향을 나타내는 변수를 만들고 해당 방향일 때 다음 x, y를 얼만큼 바꿔야하는지를 나타내는 배열을 만든다.
const direction = [[1, 0], [0, 1], [-1, -1]]; // 아래, 오른쪽, 위
위 코드가 아래로 갈 때 x,y가 다음번에 +1, +0이 되어야하고 오른쪽으로 갈 때 +0, +1, 위로 갈 때 -1, -1이 되어야 한다는 것을 의미한다.
그리고 다음 위치를 나타내는 nx
, ny
를 구한 다음에 nx
나 ny
가 배열을 넘어가거나 그 곳에 이미 값이 존재하면 방향을 바꿔준다.
이 때 마지막에 에러가 있었는데 맨 마지막 숫자는 다음 nx
,ny
가 무조건 차있기 때문에 if 문의 처음에 마지막 숫자가 아닐 때만 nx
, ny
를 검사하도록 했다.