문제
코딩테스트 연습 - 행렬 테두리 회전하기
6 6 [[2,2,5,4],[3,3,6,6],[5,1,6,3]] [8, 10, 25] 3 3 [[1,1,2,2],[1,2,2,3],[2,1,3,2],[2,2,3,3]] [1, 1, 5, 3]
programmers.co.kr
코드
function solution(rows, columns, queries) {
const map = Array.from({ length: rows }, (_, i) => {
return Array.from({ length: columns }, (__, j) => i * columns + j + 1);
});
const answer = [];
queries.forEach(([sx, sy, tx, ty]) => {
[sx, sy, tx, ty] = [sx - 1, sy - 1, tx - 1, ty - 1];
let x = sx,
y = sy;
let tmp = map[x][y];
let min = Number.MAX_SAFE_INTEGER;
while (true) {
min = min > tmp ? tmp : min;
if (x === sx && y < ty) {
[map[x][y + 1], tmp] = [tmp, map[x][y + 1]];
y++;
} else if (y === ty && x < tx) {
[map[x + 1][y], tmp] = [tmp, map[x + 1][y]];
x++;
} else if (x === tx && y > sy) {
[map[x][y - 1], tmp] = [tmp, map[x][y - 1]];
y--;
} else if (y === sy && x > sx) {
[map[x - 1][y], tmp] = [tmp, map[x - 1][y]];
x--;
if (y === sy && x === sx) break;
}
}
answer.push(min);
});
return answer;
}
풀이
그림과 같이 주어진 query에 따라 회전을 수행한다.
행렬의 값은 1부터 시작해서 각 행의 열을 우선으로 이동하면서, 1씩 증가시킨다.
그러므로 각 행렬에 선언된 값들은 (행번호 - 1) * 열크기 + 열번호 의 값을 가진다.
각 query는 직사각형의 왼쪽 위 좌표(sx, sy), 오른쪽 아래 좌표(tx, ty)를 제공함을 고려해서,
시작점 (sx, sy)로부터 시계방향으로 회전해서 다시 시작점으로 돌아오도록 코드를 작성했다.
이 회전은 현재 좌표 값(x,y)를 기준으로 코드를 작성하는데
윗변의 우측 진행, 오른쪽 변의 아래로 진행, 아랫변의 왼쪽 진행, 왼쪽 변의 위로 진행을 순서대로 구현하면 된다.
각 query의 회전을 완료할 때마다, 회전한 숫자들의 최소값을 찾고 모든 회전이 끝나면 최소값들의 배열을 반환한다.
주석을 포함한 코드
function solution(rows, columns, queries) {
const map = Array.from({ length: rows }, (_, i) => {
return Array.from({ length: columns }, (__, j) => i * columns + j + 1);
}); // 행렬 map을 행,열 크기를 반영해서 한번에 구성할 수 있다.
const answer = [];
queries.forEach(([sx, sy, tx, ty]) => { // 각각 쿼리의 4개 값을 sx, sy, tx, ty로 받는다.
[sx, sy, tx, ty] = [sx - 1, sy - 1, tx - 1, ty - 1]; // map 행렬이 (0,0)부터 시작하므로 값을 하나씩 빼준다.
let x = sx,
y = sy; // 현재 좌표 x, y값을 선언한다.
let tmp = map[x][y]; // 현재 좌표의 값을 임시변수(tmp)에 둔다.
let min = Number.MAX_SAFE_INTEGER;
while (true) {
min = min > tmp ? tmp : min; // 회전에 의해 이동하는 값이 최소값인지 판단한다.
if (x === sx && y < ty) { // 직사각형 윗변을 이동한다.
[map[x][y + 1], tmp] = [tmp, map[x][y + 1]];
y++;
} else if (y === ty && x < tx) { // 직사각형 오른쪽 변을 이동한다.
[map[x + 1][y], tmp] = [tmp, map[x + 1][y]];
x++;
} else if (x === tx && y > sy) { // 직사각형 아랫변을 이동한다.
[map[x][y - 1], tmp] = [tmp, map[x][y - 1]];
y--;
} else if (y === sy && x > sx) { // 직사각형 왼쪽 변을 이동한다.
[map[x - 1][y], tmp] = [tmp, map[x - 1][y]];
x--;
if (y === sy && x === sx) break; // 왼쪽 변을 이동하면서 원점에 돌아오면 멈춘다.
}
}
answer.push(min);
});
return answer;
}
'DS & Algorithm > programmers' 카테고리의 다른 글
[프로그래머스] 2개 이하로 다른 비트 - 자바스크립트 (0) | 2021.06.30 |
---|---|
[프로그래머스] 수식 최대화 - 자바스크립트 (0) | 2021.06.30 |
[프로그래머스] 프렌즈4블록 - 자바스크립트 (0) | 2021.06.29 |
[프로그래머스] 방금그곡 - 자바스크립트 (0) | 2021.06.28 |
[프로그래머스] 쿼드 압축 후 개수 세기 - 자바스크립트 (0) | 2021.06.28 |