[프로그래머스] Lv2. 행렬 테두리 회전하기 - javascript

fgStudy·2022년 6월 12일
0

코딩테스트

목록 보기
69/69
post-thumbnail

해당 포스팅은 프로그래머스의 행렬 테두리 풀이 다룬다. 문제 링크
코드는 javascript로 작성하였으며 시뮬레이션으로 풀이하였다.


풀이

2차원 배열 board를 회전시키는 문제이다. 스택, 시뮬레이션으로 풀이하였다.


로직 & 구현

로직 설명은 해당 포스팅을 참고하였다.

예제 1에 대해 행렬의 테두리를 회전해보자. 행렬은 테두리 왼쪽부터 시계방향으로 회전할 것이다.


1. 각 좌표값을 -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;

2. 테두리의 왼쪽 부분부터 위로 한칸씩 이동

테두리를 한칸씩 회전하면 테두리 왼쪽 부분은 [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을 업데이트 해준다.


3. 테두리의 아래쪽 부분을 왼쪽으로 한 칸씩 이동

테두리를 아래쪽 부분을 왼쪽으로 한 칸씩 이동시킨다.
이를 코드로 옮기면 다음과 같다.

for (let i=y1; i < y2; i++) {
  const moveCell = board[x2][i+1];
  board[x2][i] = moveCell;
  minNum = Math.min(minNum, moveCell);
}

4. 테두리의 오른쪽 부분을 아래쪽으로 한 칸씩 이동

이를 코드로 옮기면 다음과 같다.

for (let i=x2; i > x1; i--) {
  const moveCell = board[i-1][y2];
  board[i][y2] = moveCell;
  minNum = Math.min(minNum, moveCell);
}

5. 테두리의 위쪽 부분을 오른쪽으로 한 칸씩 이동

테두리의 위쪽 부분을 오른쪽으로 한 칸씩 이동시킨다.
이를 코드로 옮기면 다음과 같다.

for (let i=x2; i > x1; i--) {
  const moveCell = board[i-1][y2];
  board[i][y2] = moveCell;
  minNum = Math.min(minNum, moveCell);
}

6. temp를 좌표 [x1, y1+1]에 넣어주기

회전을 마쳤으므로 temp를 좌표 [x1, y1+1]에 넣어준다.

board[x1][y1+1] = temp;

7. 테두리의 최솟값 minNum을 answer에 넣어주기

회전하면서 구한 테두리의 최솟값 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;
}
profile
지식은 누가 origin인지 중요하지 않다.

0개의 댓글