const fs = require("fs");
const input = fs.readFileSync("/dev/stdin").toString().trim().split("\n");
function solution(input) {
let [N, M, R] = input
.shift()
.split(" ")
.map((str) => Number(str));
let board = input.map((str) => str.split(" ").map((str) => Number(str)));
let rotateNum = Math.min(N, M) / 2;
let minusNum = 0;
for (let j = 0; j < R; j++) {
for (let i = 0; i < rotateNum; i++) {
let num = i;
rotate(num, minusNum);
minusNum++;
}
minusNum = 0;
}
function rotate(num, minusNum) {
let startX = num; // 0
let endX = N - 1 - minusNum; // 3
let startY = num; // 0
let endY = M - 1 - minusNum; // 3
let temp = board[startX][startY];
// 맨윗줄라인을 서쪽방향으로 옮기기
for (let i = startY; i <= endY - 1; i++) {
board[startX][i] = board[startX][i + 1];
}
// 동쪽라인을 북쪽방향으로 옮기기
for (let j = startX; j <= endX - 1; j++) {
board[j][endY] = board[j + 1][endY];
}
// 맨밑쪽라인을 동쪽방향으로 옮기기
for (let k = endY; k > startY; k--) {
board[endX][k] = board[endX][k - 1];
}
// 서쪽라인을 밑으로 내리기
for (let m = endX; m > startX; m--) {
board[m][startY] = board[m - 1][startY];
}
board[num + 1][num] = temp;
}
let answer = "";
board.map((arr) => (answer += arr.join(" ") + "\n"));
return answer.trim();
}
console.log(solution(input));
이 문제에서는 단순히 끝 테두리만 배열을 돌리는게 아니라 그 안에 포함된 작은 배열들도 회전을 시키는 문제이다.
그렇기 때문에 rotateNum 이라는 변수를 통해서 크게 회전을 한번할때, 안쪽 배열들도 rotateNum만큼 회전을 해야한다.
예를 들어서 4 x 4 배열일때는 안쪽 회전시켜야할 배열이 1개, 6 x 8 배열일때는 총 겉 테두리를 제외한 배열이 속 배열이 2개 이런식으로 생기는데,
N 과 M 중에 작은 수 에서 나머지 2를 나눈것이 한번 배열을 회전할때 속배열 회전수까지 합친 총 배열 회전수이다.
그리고 배열의 기준점은 [0,0] 그리고 [1,1] , [2,2] 이런식으로 늘어나게 되고 속배열의 끝 인덱스를 구하기 위해서 minusNum 이라는 변수를 선언해주었다. 이 변수는 크게 한번 회전이 끝날때마다 초기화 시켜준다.