Bin's Blog

[프로그래머스] Level2 - 행렬 테두리 회전하기(Javascript) 본문

Algorithm

[프로그래머스] Level2 - 행렬 테두리 회전하기(Javascript)

hotIce 2023. 5. 19. 23:58
728x90
 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

▶ 문제 요약

1. rows * columns 크기인 행렬이 있다. 행렬은 1부터 rows * columns까지의 숫자가 한 줄씩 순서대로 적혀있다.

2. 직사각형 모양의 범위를 여러 번 선택해, 테두리 부분에 있는 숫자들을 시계방향으로 회전해야 한다. 

3. 각 회전들을 배열에 적영한 뒤, 그 회전에 의해 바뀐 숫자들 중 가장 작은 숫자들을 순서대로 배열에 담아 return해라.

 

▶ 정답 코드

function solution(rows, columns, queries) {
    let answer = [];
    // 0으로 찬 배열 만들기
    let board = Array.from(Array(rows), () => 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) {
        // 인덱스 0 시작이니까 -1을 빼주고
        let [x1, y1, x2, y2] = query.map(el => el-1);
        // 회전 기준값
        let standard = board[x1][y1];
        // 최솟값;
        let min = standard;
        
        // 위로 이동
        for (let i = x1; i < x2; i++) {
            board[i][y1] = board[i+1][y1]
            min = Math.min(min, board[i][y1]);
        }
        // 왼쪽 이동
        for (let i = y1; i < y2; i++) {
            board[x2][i] = board[x2][i+1]
            min = Math.min(min, board[x2][i]);
        }

        // 아래 이동
        for (let i = x2; i > x1; i--) {
            board[i][y2] = board[i-1][y2]
            min = Math.min(min, board[i][y2]);
        }
        // 오른쪽 이동
        for (let i = y2; i > y1; i--) {
            board[x1][i] = board[x1][i-1]
            min = Math.min(min, board[x1][i]);
        }
        // 회전 기준값을 한칸 옆으로 이동
        board[x1][y1+1] = standard;
        
        // 최솟값 넣기
        answer.push(min);
    }
    return answer
}

 

▶ 풀이 과정

1. rows * columns 크기에 해당하는 배열을 0으로 채운다. 

 

2. 그리고 2중 for문을 사용해서 값을 순서대로 채우는데 문제의 설명에 따르면 행렬의 초기 상태에서 i행 j열에 있는 숫자는 ((i-1) * column +j)인데 문제에서 제공하는  i, j가 1부터 시작하는데 프로그래밍에서 인덱스는 0부터 시작하니 0부터 시작하는 인덱스에 맞게 조정해야한다. 그래서 (i * columns + j + 1)을 하면 값이 알맞게 채워진다. 

 

3. 그리고 queries를 돌면서 4개의 행을 map()함수를 사용해서 1을 빼줘야한다. 프로그래밍 인덱스는 0이 시작값이니까 조정해준다. 

 

4. 현재 시계방향으로 회전하는 기준값을 잃지 않기 위해서 변수에 담아 놓는다. 최솟값도 찾아야하니 첫 번째 테두리 값을 넣는다. 

 

5. 4가지 방향으로 이동하는데 위 방향부터 보면 범위는 (시작행 ~ 끝행)으로 설정했다. 위 방향은 예를 들어 (1, 1) => (0, 1)이 된다. 행이 움직이고 열은 고정이다. 그래서 board[0][1] = board[1][1] 이게 식이다. 아마 반대로 되서 햇갈릴 수 있다. 시작행이 2행이고 끝행이 5행이라면 우리는 4행의 값은 5행이 되어야 한다. 위로 이동하니까 이런 원리로 시작행 ~ 끝행까지 보면 된다. [y1(시작열)] 이 뒤에 열로 들어갔냐면 왼쪽 테두리를 처리하기 때문이다. 그러니까 우리는 y1열만 위로 이동시키면 된다.  

 

5.1 왼쪽 방향도 비슷하다. 왼쪽 방향의 범위는 (시작열 ~ 끝열)이다. (1, 2) => (1,1)이다. 열은 움직이고 행은 고정이다. 그래서 board[1][1] = board[1][2] 이렇게 움직인다. 우리가 처음에 왼쪽 방향을 움직이는 것은 가장 오른쪽 테두리 끝 지점이다. 그럼 행은 고정이니까 가장 끝행인 [x2]가 들어가야한다. 왼쪽방향은 가장 끝 행에서 열만 움직인다. 

 

5.2 아래 방향은 위에 두 방향과 다르다. (끝행 ~ 시작행이다) (1,1) => (2,1)이다. 행은 움직이고 열은 고정이다. 그래서 board[2][1] = board[1][1]이다. 점점 숫자가 줄어들어야한다. 그래서 감소시켜야한다. 여기에서 아래 방향은 가장 오른쪽 테두리 부분에서만 필요하니까 거기에 가장 끝 열인 [y2]가 들어가야한다.  

 

5.3 오른쪽 방향도 아래 방향과 비슷하다 . (끝열 ~ 시작열이다) (3,1) => (3,2)이다. 열은 움직이고 행은 고정이다. 그래서 board[3][2] = board[3][1]이다. 점점 열의 숫자가 줄어들어야한다. 여기에서 오른쪽 방향은 가장 위에 테두리 부분에서만 필요하니까 거기에 시작 열인 [x1]가 들어가야한다.  

 

6. 회전 기준값을 다음 열로 이동시켜야 한다. 

 

7.  결과값 출력

728x90