Unravelling the Matrix Array.

Recently I had a code challenge where I had to unroll a NxN matrix array. I’m going to go through my thought process in hopes of reinforcing my thinking or finding a more efficient solution.

Image for post
Image for post

Given an array matrix, unroll the array in clockwise rotation.

// Sample Array (4 x 4 matrix)
// 1 2 3 4
// 12 13 14 5
// 11 16 15 6
// 10 9 8 7
matrix = [[1, 2, 3, 4], [12, 13, 14, 5], [11, 16, 15, 6], [10, 9, 8, 7]]// expected output
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]

At first I asked, can i flatten the array and sort it? The answer was a no. Couldn’t hurt to ask lol.

Before coding anything I immediately grabbed a pen and paper and drew out the matrix array. I drew a spiral and thought, what do I need to do to grab these numbers in this order.

Image for post
Image for post

The way I saw it was, I need to get the top row. Then the right side. Followed by the bottom. Up the left. Repeat.

Once I thought I had the logic figured out I started planning out my code.

function unrollMatrix(matrix){    // grab top row    // grab right column    // grab bottom row and reverse it    // grab left column and reverse it}

How to grab the top row…

I know the top row is the first index in the array. So I’ll move that row into a new array and mutate it at the same time.

function unrollMatrix(matrix){   let unrolled = []// grab top row   unrolled = [...unrolled, matrix.shift()]// grab right column// grab bottom row and reverse it// grab left column and reverse it}

Ok… now the right column.

My thought was to iterate through each remaining set of arrays and grab the last item while also mutating it.

function unrollMatrix(matrix){    let unrolled = []// grab top row    unrolled = [...unrolled, matrix.shift()]// grab right column    unrolled = [...unrolled, matrix.map(row => row.pop())]// grab bottom row and reverse it// grab left column and reverse it}

So now I have [ [ 1, 2, 3, 4 ], [ 5, 6, 7 ] ]. Not exactly the expected output but I can flatten it later. Moving on to the bottom row. I can pop the last index, but then I have to reverse it.

function unrollMatrix(matrix){    let unrolled = []// grab top row    unrolled = [...unrolled, matrix.shift()]// grab right column    unrolled = [...unrolled, matrix.map(row => row.pop())]// grab bottom row and reverse it
unrolled = [...unrolled, matrix.pop().reverse()]
// grab left column and reverse it}

Almost there. unrolled at this point = [ [ 1, 2, 3, 4 ], [ 5, 6, 7 ], [ 8, 9, 10 ] ]. Now to grab the left column. Just like I did the right column, I could do the left column and then reverse it.

function unrollMatrix(matrix){    let unrolled = []// grab top row    unrolled = [...unrolled, matrix.shift()]// grab right column    unrolled = [...unrolled, matrix.map(row => row.pop())]// grab bottom row and reverse it    unrolled = [...unrolled, matrix.pop().reverse()]// grab left column and reverse it     unrolled = [...unrolled, matrix.map(row => row.shift()).reverse()]}

So now that I’m grabbing everything in a spiral, I just have to keep repeating this process until its done. What came to my mind was to create a while loop that will repeat until there’s nothing left in the matrix array and everything is in the new unrolled array. Also need to fix the output so I’ll flatten the return.

function unrollMatrix(matrix){let unrolled = []while (matrix.length > 0) {// grab top row    unrolled = [...unrolled, matrix.shift()]// grab right column    unrolled = [...unrolled, matrix.map(row => row.pop())]// grab bottom row and reverse it    unrolled = [...unrolled, matrix.pop().reverse()]// grab left column and reverse it    unrolled = [...unrolled, matrix.map(row => row.shift()).reverse()]
}
return unrolled.flat()}
Image for post
Image for post

With the while loop, the function should be able to complete any size matrix the same way.

Fullstack Software Engineer

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store