Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to rotate a given matrix by one element clockwise in JavaScript

Ok so I came up with this code I would like to implement in JS but I am not very advanced in JS and I am having trouble printing it out or even testing it...could anyone check the code and help me console.log it?

this is my goal:

┌     ┐    ┌     ┐ 
|1 2 3|    |4 1 2| 
|4 5 6| -> |7 5 3| 
|7 8 9|    |8 9 6|   
└     ┘    └     ┘

This is the code I wrote:

var matrix = [ [ 1, 2, 3 ], [ 4, 5, 6 ], [ 7, 8, 9 ] ];

function rotateMatrix(matrix) {
	//boundery indication for row and column (index)
	let maxRow = matrix.length - 1;
	let maxCol = matrix.length - 1;
	let row = 0;
	let col = 0;

	//keeps track of ring which we are working with
	while (row < maxRow && col < maxCol) {
		// initial temp starting with 4 being the numb. moving clockwise
		let previous = matrix[row + 1][col];

		//loop through TOP ROW (row 0 ) moving 1 spot
		for (let i = col; i <= maxCol; i++) {
			let current = matrix[row][i]; //current makes space for previous starting w/1
			matrix[row][i] = previous; // putting final num in new spot starting w/4 putting in slot 1
			previous = current; //leaving the loop with previous = 3
		}
		row++; //moves to row index 1

		//starting in row index 1 loop through RIGHT most COLUMN (col 2) moving 1 spot down
		for (let j = row; j <= maxRow; j++) {
			let current = matrix[j][maxCol]; //current makes space for previous starting w/6
			matrix[j][maxCol] = previous; //starting with 3 moving in slot 6
			previous = current; //leaving the loop with previous = 9
		}
		maxCol--; //changes maxCol to index 1

		//loop through the BOTTOM ROW (row 2) moving 1 spot left
		for (let j = maxCol; j >= col; j--) {
			//starting in col index 1 decrementing down to col 0
			let current = matrix[maxRow][j]; //current makes space for previous starting w/8
			matrix[maxRow][j] = previous; //starting with 9 moving in slot 8
			previous = current; //leaving the loop with previous = 7
		}
		maxRow--; //changes maxRow to index 1

		//loop through the LEFT COLUMN (col 0) moving 1 spot up

		for (let i = maxRow; i >= row; i--) {
			//starting in row index 1 decrementing down to row 0
			let current = matrix[i][col]; //current makes space for previous starting w/4
			matrix[i][col] = previous; //starting with 7 moving in slot 4
			previous = current; //leaving the loop with previous = 4
		}
	}
}

///////

console.log(matrix.map(x=>x.join()));
rotateMatrix(matrix);
console.log(matrix.map(x=>x.join()));
like image 517
Valiant Lupori Buzzactaxe Avatar asked Sep 05 '25 02:09

Valiant Lupori Buzzactaxe


1 Answers

For rotating clockwise, you have to go around counter-clockwise. Also, the element you store at the beginning will be needed at the end, and it is not needed anywhere else.

function p(m){
  for(let l of m)
    console.log(l.join());
  console.log('---');
}
function ccwrectangle(mtx,top,left,bottom,right){
  let elem=mtx[top][left];
  for(let y=top;y<bottom;y++)           // downwards on the left
    mtx[y][left]=mtx[y+1][left];
  for(let x=left;x<right;x++)           // righwards at the bottom
    mtx[bottom][x]=mtx[bottom][x+1];
  for(let y=bottom;y>top;y--)           // upwards on the right
    mtx[y][right]=mtx[y-1][right];
  for(let x=right;x>left+1;x--)         // leftwards on the top
    mtx[top][x]=mtx[top][x-1];
  mtx[top][left+1]=elem;
}

let m1=[[1,2,3],[4,5,6],[7,8,9]];
p(m1);
ccwrectangle(m1,0,0,2,2);
p(m1);

let m2=[[1,2,3,4],[5,6,7,8],[9,'A','B','C'],['D','E','F','0']];
p(m2);
ccwrectangle(m2,0,0,3,3);
ccwrectangle(m2,1,1,2,2);
p(m2);

ccwrectangle() rotates one "ring" at a time, so for matrices with multiple rings it runs multiple times. The general way for square matrices would be something like

for(let a=0,b=mtx.length-1;b>a;a++,b--)
  ccwrectangle(mtx,a,a,b,b);

(Also for rectangular ones after all, just in that case left-right and top-bottom pairs have to be tracked separately and the loop ends when any one of the pairs meet)

like image 149
tevemadar Avatar answered Sep 07 '25 21:09

tevemadar