[programmers] 행렬 테두리 회전하기 #JavaScript
LEVEL 2 : 행렬 테두리 회전하기
- IN
rows, columns, queries - OUT
회전한 숫자 중 min
먼저, rows * columns 크기의 2차원 배열을 만들어준다..!
그리고 1 부터 rows * columns 까지 숫자를 순서대로 하나씩 넣어줄 것이다.
var arr = []; // 숫자 행렬을 만들 변수
for(var i = 0; i<rows ; i++){ // 행수 만큼 돌리기
var a = []; // 임시 배열
for(var j = 0 ; j<columns ; j++){ // 열수 만큼 돌리기
a.push(columns * i + j + 1); // 숫자 하나씩 배열 만들기
}
arr.push(a); // 배열 한 줄 넣기
}
숫자 순서대로 넣을 규칙을 찾아냈다..!
배열의 index 는 0으로 시작하니 0부터 기준을 잡고,
한 줄에 1부터 columns 까지 채운다면,
이 줄의 규칙은 j+1!
다음 줄에서도 1부터 columns 까지 채운다.
물론, 이전 줄 길이 값인 columns을 더해준다.
호옹이 뭔가 벌써 규칙이 보이기 시작했지 않은가...!
아니, 아직 모를 수 도 있다. 다시 다음 줄을 진행해본다.
1부터 columns 까지 채우기 전에!! 이전 줄 길이 값인 columns 를 두번 더해준다. 왜냐구? 이전 줄이 두 줄이잖아~
유레카! columns이 어떠한 배수로 증가하는 거 같다.
여기서 잠깐!
임의의 정수 N에 대하여 0을 곱하면 0, 1을 곱하면 N이다.
그럼 여기서 살짝 아쉬운 부분에 손을 살짝 대보았다.
그 어떠한 숫자는 0부터 증가중인 것을 볼 수 있다. 바로 i 였다.
요로코롬 columns * i + j + 1 도출!
(어차피 곱셈 연산 우선순위가 높으니, 괄호는 모두 생략)
제한사항에 "i 행 j 열에 있는 숫자는 ((i-1) x columns + j)입니다." 라고 친절히 적혀있었지만,
까막눈봄씨는 그림을 그려 규칙을 찾아냈다는 슬픈 이야기였다...
물론, 게시글은 깔끔하게 보이기 위해 엑셀로 정리^^
.push() 를 이용하여 값 하나씩 넣어 1차원 배열을 만들었고,
이렇게 만들어진 1차원 배열을 또 다른 1차원 배열에 push!!
너무 자바스럽나..? 이 외에 더 간단한 방법이 있을 거 같다.
REF. 충격적인!! 어느 한 분의 한 줄 숏코딩
const a = [...Array(rows)].map((_, r)=>[...Array(columns)].map((_, c)=>r*columns+c+1));
JS린이는 해석도 못하겠습니다만... 득도하겠습니다..
이제 다음 단계!! 숫자 돌려돌려 돌림판~~
queries.forEach(e => {
// index 기준으로 세팅
var x1 = e[0] -1;
var y1 = e[1] -1;
var x2 = e[2] -1;
var y2 = e[3] -1;
var min = rows * columns; // 회전수 중 최솟값
var tmp = arr[x1][y2]; // 숫자 회전을 위한 임시 변수
// 1
for(var a = y1; a < y2 ; a++ ){ // x1 고정
var t = arr[x1][a];
arr[x1][a] = tmp;
tmp = t;
if( arr[x1][a] <= min ){
min = arr[x1][a];
}
}
// 2
for(var b = x1; b < x2 ; b++ ){ // y2 고정
var t = arr[b][y2];
arr[b][y2] = tmp;
tmp = t;
if( arr[b][y2] <= min ){
min = arr[b][y2];
}
}
// 3
for(var c = y2; c > y1 ; c-- ){ // x2 고정
var t = arr[x2][c];
arr[x2][c] = tmp;
tmp = t;
if( arr[x2][c] <= min ){
min = arr[x2][c];
}
}
// 4
for(var d = x2; d > x1 ; d-- ){ // y1 고정
var t = arr[d][y1];
arr[d][y1] = tmp;
tmp = t;
if( arr[d][y1] <= min ){
min = arr[d][y1];
}
}
// 마무리
arr[x1][y1] = tmp;
if( arr[x1][y1] <= min ){
min = arr[x1][y1];
}
answer.push(min);
});
어디서 본 건 있어서... forEach 를 써보았다..!
queries의 행수만큼 루프 돌 것이다.
queries 데이터는 "1 ≤ x1 < x2 ≤ rows, 1 ≤ y1 < y2 ≤ columns"
로 지정되어 있으니, 입력값 검증은 안해도 무관~
다만 배열 index 기준으로 코딩을 위해 다들 -1 해줍니다.
최솟값을 저장할 변수는 행렬 내 가장 큰 값으로 default~
이제 그림을 또 그려 볼까요..?
처음에는 무작정 이중for문으로 순서대로 돌렸는데, 시계방향 회전이었다..! 바본가?
그래서 코로NA도 4단계인김에 회전도 4단계로 나누었다.
(이것은 마무리까지 4.5단계?ㅎ)
1번째 회전에선 y1 고정, x 증가
2번째 회전에선 x2 고정, y 증가
3번째 회전에선 y2 고정, x 감소
4번째 회전에선 x1 고정, y 감소
각 꼭짓점은 시작점만 포함해서 돌리기로 한다.
제일 처음에는 임시 변수 tmp에 1번째 시작점 값을 넣는다.
회전시에 각 점의 값과 tmp 값을 swapping! 그것을 반복~!
swapping 하는 김에 최소값인지까지 확인해주기로 하자.
행렬 내 가장 큰 값으로 넣었으니 안심하고 비교해서 작거나 같을 때 넣으면 되겠다.
제일 마지막에 다시 시작점으로 돌아온 부분만 한 줄 더 추가!
혹시 모르니 이것도 최솟값 비교! (<- 이 부분 깜빡하고 빼먹으니, case 3~11 통과가 안됐다.ㅠ)
최종 최솟값을 answer에 push~push~baby~ 해주면 되겠다!!
최솟값 비교시 이런 방법도 있었다...
min = Math.min(min, tmp);
아무튼
(다음 풀이때는 점수있는 짤을 넣고싶다.)
Author And Source
이 문제에 관하여([programmers] 행렬 테두리 회전하기 #JavaScript), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@bomine/programmers-행렬-테두리-회전하기저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)