해당 포스팅은 프로그래머스의 행렬 테두리 풀이 다룬다. 문제 링크
코드는 javascript로 작성하였으며 시뮬레이션으로 풀이하였다.
2차원 배열 board를 회전시키는 문제이다. 스택, 시뮬레이션으로 풀이하였다.
로직 설명은 해당 포스팅을 참고하였다.
예제 1에 대해 행렬의 테두리를 회전해보자. 행렬은 테두리 왼쪽부터 시계방향으로 회전할 것이다.
회전하는 테두리의 좌표값을 [x1, y1, x2, y2]라고 하자. 좌표가 1부터 시작하므로 각각 -1를 해주어야 한다
예컨대 예제 1의 경우 회전하는 테두리의 좌표값은 [2,2,5,4]이다. 각각의 좌표값을 -1해주면 [1,1,4,3]이 된다.
이를 코드로 옮기면 다음과 같다.
let [x1,y1,x2,y2] = query;
x1 -=1; y1 -=1; x2 -=1; y2 -=1;
테두리를 한칸씩 회전하면 테두리 왼쪽 부분은 [8,14,20,26]에서 [14,20,26,27]이 되어야 한다. 각 셀을 위로 한 칸씩 이동시키면 [14,20,26,26]이 된다.
가장 끝 부분인 26은 테두리의 아래 부분을 왼쪽으로 한칸씩 옮길 때 27로 변경된다.
왼쪽 부분의 가장 윗 부분인 8은 회전하고 마지막에 업데이트 해줄 것이므로 미리 변수 temp에 저장해준다.
이를 코드로 옮기면 다음과 같다.
let temp = board[x1][y1];
let minNum = temp;
for (let i=x1; i < x2; i++) {
const moveCell = board[i+1][y1];
board[i][y1] = moveCell;
minNum = Math.min(minNum, moveCell);
}
코드에서 minNum은 회전할 때마다 최솟값을 체크하기 위함이다.
문제에서 각 테두리 회전 후 이동된 숫자 중 가장 작은 값을 차례대로 배열에 담아서 리턴하라고 나와있다. 따라서 먼저 minNum을 temp로 초기화한 다음, 회전을 하면서 minNum을 업데이트 해준다.
테두리를 아래쪽 부분을 왼쪽으로 한 칸씩 이동시킨다.
이를 코드로 옮기면 다음과 같다.
for (let i=y1; i < y2; i++) {
const moveCell = board[x2][i+1];
board[x2][i] = moveCell;
minNum = Math.min(minNum, moveCell);
}
이를 코드로 옮기면 다음과 같다.
for (let i=x2; i > x1; i--) {
const moveCell = board[i-1][y2];
board[i][y2] = moveCell;
minNum = Math.min(minNum, moveCell);
}
테두리의 위쪽 부분을 오른쪽으로 한 칸씩 이동시킨다.
이를 코드로 옮기면 다음과 같다.
for (let i=x2; i > x1; i--) {
const moveCell = board[i-1][y2];
board[i][y2] = moveCell;
minNum = Math.min(minNum, moveCell);
}
회전을 마쳤으므로 temp를 좌표 [x1, y1+1]에 넣어준다.
board[x1][y1+1] = temp;
회전하면서 구한 테두리의 최솟값 minNum을 answer에 넣어준다.
return minNum;
// x = 열, y = 행
function solution(rows, columns, queries) {
const answer = [];
const board = [...Array(rows)].map(() => [...Array(columns)].fill(0));
for (let i = 0; i < rows; i++) {
for (let j = 0; j < columns; j++) {
board[i][j] = (i * columns) + (j+1);
}
}
for (let query of queries) {
const minNum = rotation(board, query);
answer.push(minNum);
}
return answer;
}
function rotation(board, query) {
let [x1,y1,x2,y2] = query;
x1 -=1; y1 -=1; x2 -=1; y2 -=1;
let temp = board[x1][y1];
let minNum = temp;
for (let i=x1; i < x2; i++) {
const moveCell = board[i+1][y1];
board[i][y1] = moveCell;
minNum = Math.min(minNum, moveCell);
}
for (let i=y1; i < y2; i++) {
const moveCell = board[x2][i+1];
board[x2][i] = moveCell;
minNum = Math.min(minNum, moveCell);
}
for (let i=x2; i > x1; i--) {
const moveCell = board[i-1][y2];
board[i][y2] = moveCell;
minNum = Math.min(minNum, moveCell);
}
for (let i=y2; i > y1; i--) {
const moveCell = board[x1][i-1];
board[x1][i] = moveCell;
minNum = Math.min(minNum, moveCell);
}
board[x1][y1+1] = temp;
return minNum;
}