Last active
March 31, 2018 01:47
-
-
Save johnoscott/f7bd77bc020fdefe31fb025558ce9ded to your computer and use it in GitHub Desktop.
[Matrix Rotation] Javascript implementation of 90degree clockwise rotation of nxn matrix
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!doctype html> | |
<html lang="en"> | |
<head> | |
<meta charset="utf-8"> | |
<title>GistRun</title> | |
<!--<link rel="stylesheet" href="styles.css">--> | |
</head> | |
<body> | |
<h1>Hello world!</h1> | |
<script src="rotate-matrix.js"></script> | |
<script src="run.js"></script> | |
</body> | |
</html> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* @param {number[][]} matrix | |
* @return {void} Do not return anything, modify matrix in-place instead. | |
*/ | |
var rotate = function(m) { | |
const debug = false; | |
// strategy : | |
// starting with the outer 'ring' of edges, rotate each cell in place | |
// and work inward until we reach the middle | |
// note: matrix is square (nxn) so an in-place rotation will work | |
// outer loop "i" is a starting offset of the top-left cell | |
// e.g. (0,0), (1,1), (2,2) ect | |
// limit is the center of the matrix | |
// so if dimension of the matrix is d, then loop limit is (i < (d-1) / 2); | |
const d = m[0].length; // dimension size of the matrix | |
const e = d-1; // index bounds of matrix | |
const row=0,col=1; // for clarity | |
debug && console.log(`dimension is ${d}x${d}`) | |
// move cell a -> b | |
// a and b are cell references [ row,col ] | |
// which need to be accessed in reverse : row y first, then column x | |
const moveCell = (a,b,msg) => { | |
debug && console.log(` move [${a[row]},${a[col]}]=${m[a[row]][a[col]]} -> [${b[row]},${b[col]}] : ${msg} `) | |
m[b[row]][b[col]] = m[a[row]][a[col]]; | |
} | |
const setCell = (a,val,msg) => { | |
debug && console.log(` set [${a[row]},${a[col]}] -> ${val} : ${msg} `) | |
m[a[row]][a[col]] = val; | |
} | |
const getCell = (a,msg) => { | |
const val = m[a[row]][a[col]]; | |
debug && console.log(` get [${a[row]},${a[col]}] = ${val} : ${msg} `) | |
return val; | |
} | |
for (let i=0; i < (d-1) / 2; i++) { | |
const w = d - (i*2); // width of this ring | |
// const w = d - (i*2); // width of this ring | |
const colOffset = i; | |
debug && console.log(`\nrotate ring i=${i} width=${w} offset=${colOffset}`); | |
// swap each cell in clockwise direction | |
// store the top edge value, then move left->top, bottom->left, right->bottom, then move saved top -> right | |
// bounds of this loop is the width of this ring -1 because the last cell of each edge is the first of the next edge | |
for (let j=0; j< w-1; j++) { | |
debug && console.log(`\n ~~ ${j} until ${w-1}`); | |
const top = [i, i+j]; | |
const right = [i+j, e-i]; | |
const bottom = [e-i,e-i-j]; | |
const left = [e-i-j,i]; | |
// temp store top | |
const tempTopVal = getCell(top, 'top'); | |
// left -> top | |
moveCell(left, top , 'left -> top'); | |
// bottom -> left | |
moveCell(bottom, left, 'bottom -> left'); | |
// right -> bottom | |
moveCell(right, bottom, 'right -> bottom'); | |
// saved top -> right | |
setCell(right, tempTopVal, 'top -> right'); | |
} | |
} | |
// return m | |
}; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const m1 = [ | |
[5] | |
]; | |
const m2 = [ | |
[2,3], | |
[1,4] | |
]; | |
const m3 = [ | |
[3,4,5], | |
[2,9,6], | |
[1,8,7] | |
]; | |
const m4 = [ | |
[4, 5, 6, 7], | |
[3, 14, 15, 8], | |
[2, 13, 16, 9], | |
[1, 12, 11, 10] | |
]; | |
const m5 = [ | |
[5,6 ,7 ,8 , 9], | |
[4,19,20,21,10], | |
[3,18,25,22,11], | |
[2,17,24,23,12], | |
[1,16,15,14,13], | |
]; | |
function test(m) { | |
const format = m => m.map(row => JSON.stringify(row)) | |
.join('\n') | |
console.log('\n ======================='); | |
console.log('Input: \n'); | |
console.log(format(m)); | |
console.log('\nClockwise Rotation: \n'); | |
rotate(m); | |
console.log(format(m)); | |
} | |
test(m1); | |
test(m2); | |
test(m3); | |
test(m4); | |
test(m5); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment