
문제 설명
양의 정수 n이 매개변수로 주어집니다. n × n 배열에 1부터 n2 까지 정수를 인덱스 [0][0]부터 시계방향 나선형으로 배치한 이차원 배열을 return 하는 solution 함수를 작성해 주세요.
입출력 예
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] ]
일단 문제 자체를 이해하지 못했다.저게 어떤 식으로 나선형이란 말인지? 생각했는데 다른 분이 주석으로 한번에 그려주신 것을 보고 바로 이해가 갔다. (출처: https://sefact.github.io/posts/181832/)
[0][0] → [0][1] → [0][2] → [0][3] <<이건 인덱스 번호를 뜻함
↓ ↓
[1][0] → [1][1] → [1][2] [1][3]
↑ ↑ ↓ ↓ ↓ ↓
[2][0] [2][1] ← [2][2] [2][3]
↑ ↑ ↓ ↓
[3][0] ← [3][1] ← [3][2] ← [3][3]
아...말 그대로 나선형으로 배치해야 한다는 말이군요?
물론 문제를 이해했다고 로직까지 한번에 생각할 수준은 되지 않는다.
몇 번을 반복문을 돌리며 시행착오를 하다가 하루 내로 풀지 못할것 같아 검색을 했다.
function solution(n) {
let array = new Array(n).fill().map(() => new Array(n).fill(0)),
row = 0,
col = 0,
value = 1,
direction = 'right';
while(value <= n * n){
array[row][col] = value++;
if(direction == 'right'){
if(col == n - 1 || array[row][col + 1] !== 0){
direction = 'down';
row++;
}else{
col++;
}
}
else if(direction == 'down'){
if(row == n - 1 || array[row + 1][col] !== 0){
direction = 'left';
col--;
}else{
row++;
}
}
else if(direction == 'left'){
if(col == 0 || array[row][col - 1] !== 0){
direction = 'up';
row--;
}else{
col--;
}
}
else if(direction == 'up'){
if(row == 0 || array[row - 1][col] !== 0 ){
direction = "right";
col++;
}else{
row--;
}
}
}
return array;
}
let array = new Array(n).fill().map(() => new Array(n).fill(0)),
row = 0,
col = 0,
value = 1,
direction = 'right';
array
어쨌든 리턴할 결과물은 배열이기 때문에 n의 개수만큼 0으로 채워진 배열을 생성한다.
처음에 나는 new Array(n).fill([]) 과 같이 단순하게 처리했으나, 이렇게 되면 [[],[],[],[]]과 같이 빈 배열만 생성되므로 배열의 몇번째 인덱스인지 반복문에서 처리하지 못해 코드 자체가 돌아가지 않는다.그렇기 때문에 [[0,0,0,0], [0,0,0,0], [0,0,0,0], [0,0,0,0]]이와 같이 0으로 채워진 배열이라도 만들어 주는 것.
row , col
각각 행, 열이 될 변수다. 부끄러운 이야기지만 나는 아직도 행과 열이 어디인지 계속 헷갈린다.
행 : 세로로 읽는 y축 숫자
열 : 가로로 읽는 x축 숫자

value
각각의 배열에 들어가며 증가할 숫자다. 1에서 n * n까지라고 보면 되겠다.
direction
방향을 나타낼 변수가 왜 필요하지? 생각했는데 의외로 많은 분들이 방향 변수를 추가하셨다. 아마 if문에서 판별하기 위해 사용하는 듯 싶다.
while(value <= n * n){
array[row][col] = value++;
.
.
.
처음 조건은 value가 n * n 의 값을 가질때까지 반복문을 돌리는 것이다.
각 행/열마다 1씩 증가된 value 값을 넣어준다.
if(direction == 'right'){
if(col == n - 1 || array[row][col + 1] !== 0){
direction = 'down';
row++;
}else{
col++;
}
}
오른쪽으로 한 칸씩 이동하며 row 혹은 col이 증가한다.

col == n - 1n은 4이기 때문에 맨 마지막 열은 n - 1 이 될 수밖에 없다.그렇기 때문에 col이 n - 1 값과 같아지면 방향을 바꿔야 한다. array[row][col + 1] !== 0array[0][2]에 들어가 있는건 3이라는 숫자다. 처음 시작할땐 col == n - 1 를 판별하는 과정에서 알아서 바뀌겠지만, array[1][0] 번째부터 다시 오른쪽으로 방향을 틀어 나가야 하기 때문에 이 조건이 필요하다. array[1][3]에는 이미 세로로 내려오면서 5라는 값이 들어가 있기 때문이다.else if(direction == 'down'){
if(row == n - 1 || array[row + 1][col] !== 0){
direction = 'left';
col--;
}else{
row++;
}
}
if가 아니라 else if문으로 처리한것에 주목하기. 한번의 반복때 상하좌우를 한꺼번에 판별해야 해서 쓰는 것 같다. 만약 if문으로만 처리했으면 순차적으로 처리가 되었을 것이다.
어쨌든 여기서도 하나의 분기를 통해 방향이 바뀐다.
row == n - 1n이 4라고 하면, 행의 맨 마지막도 n - 1이다. 처음 아래로 이동할 때를 위한 빌드업 조건.array[row + 1][col] !== 0array[2][3]에는 이미 왼쪽을 지나오며 8이라는 숫자가 있으니까 방향을 바꾼다.else if(direction == 'left'){
if(col == 0 || array[row][col - 1] !== 0){
direction = 'up';
row--;
}else{
col--;
}
}
col == 0array[0][n]은 무조건 첫 번째 열이니 그럴만도 하다.array[row][col - 1] !== 0array[0][2] 에는 위로 올라오면서 11이라는 숫자가 이미 있기 때문에 방향을 바꾼다.row나 col이 1씩 감소하는데, 이는 말 그대로 왼쪽/위쪽으로 이동하기 위해 n-1까지 증가한 값을 하나씩 빼주어야 하기 때문이다. else if(direction == 'up'){
if(row == 0 || array[row - 1][col] !== 0 ){
direction = "right";
col++;
}else{
row--;
}
}
row == 0array[n][0]이 되었을때 방향을 바꾼다.array[row - 1][col] !== 0처음 위 코드를 보고 썼을때는 왜 이런 식으로 작성해야 하지?라며 의문이 가는 부분이 있었는데 역시 이해가 안 될때는 코드를 한줄씩 해석하며 이해하는게 도움이 되는 것 같다. 나중에는 다른 풀이방식도 해석해봐야겠다.