user6895092 - 1 year ago 142
Javascript Question

# how to spirally traverse a matrix recursively - javascript

Please look at this JSFiddle: https://jsfiddle.net/hc2jcx26/

I am trying to spirally traverse a matrix

`output`
(any size) so that it prints each element in spiral order to
`console.log`
every 2 seconds:

``````var output = [[0, 1, 2, 3],
[4, 5, 6, 7]];

function spiralOrder(output) {
var rows = output.length;
var columns = output[0].length;
var top = 0;
var down = rows - 1;
var left = 0;
var right = columns - 1;
var result = [];

var side = 'top';
var i;

while(top <= down && left <= right) {

if (side === 'top') {

(function myLoop (i) {
setTimeout(function () {
console.log(output[top][i]);
if (++i <= right) myLoop(i); //READ LEFT TO RIGHT FROM TOP, IS THIS NOT CORRECT?
}, 2000)
})(left);

top++;
side = 'right';
continue;
}
if (side === 'right') {

(function myLoop (i) {
setTimeout(function () {
console.log(output[i][right]);
if (++i <= down) myLoop(i);   //READ TOP TO BOTTOM FROM RIGHT
}, 2000)
})(top);

right--;
side = 'bottom';
continue;
}
if (side === 'bottom') {

(function myLoop (i) {
setTimeout(function () {
console.log(output[down][i]);
if (--i >= left) myLoop(i);    //READ RIGHT TO LEFT FROM BOTTOM
}, 2000)
})(right);

down--;
side = 'left';
continue;
}
if (side === 'left') {

(function myLoop (i) {
setTimeout(function () {
console.log(output[i][left]);
if (--i >= top) myLoop(i);    //READ BOTTOM TO TOP FROM LEFT
}, 2000)
})(down);

left++;
side = 'top';
continue;
}
}
}
``````

I am expecting this output:

``````0
1 //after 2 seconds delay
2 //after 2 seconds delay
3 //etc.
7
6
5
4
``````

But I am not getting this with the code above. The output is all over the place and doesn't even have the right number of elements. I am using recursion to add a delay in my loop after every iteration (through
`setTimeout`
), but I do not think I am setting the variables correctly. But when I look at the code, it makes sense to me. What am I missing here?

This is my approach to your problem. I didn't use recursivity though.

``````var matrix1 = [
[1, 2, 3, 4],
[5, 6, 7, 8],
[9, 10, 11, 12],
[13, 14, 15, 16]
], matrix2 = [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9],
[10, 11, 12]
], matrix3 = [
[0, 1, 2, 3],
[4, 5, 6, 7]
], matrix4 = [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9]
];

(function (matrix) {
var i,
nRows = matrix.length,
nCols = matrix[0].length,
rowLimit = nRows - 1,
colLimit = nCols - 1,
rounds = 0,
printedElements = 0,
nElements = nRows * nCols,
timeoutLapse = 2000;

function print(val) {
printedElements += 1;
setTimeout(function () {
console.log(val);
}, printedElements * timeoutLapse);
}

do {
for (i = rounds; i <= colLimit - rounds; i += 1) {// from left to right
print(matrix[rounds][i]);
}

for (i = rounds + 1; i <= rowLimit - rounds; i += 1) {// from top to bottom
print(matrix[i][colLimit - rounds]);
}

for (i = colLimit - rounds - 1; i >= rounds; i -= 1) {// from right to left
print(matrix[rowLimit - rounds][i]);
}

for (i = rowLimit - rounds - 1; i >= rounds + 1; i -= 1) {// from bottom to top
print(matrix[i][rounds]);
}
rounds += 1;
} while (printedElements < nElements);

})(matrix4);
``````

I added some examples in order to test it. I just print out elements of the matrix every two seconds following the spiral pattern. When all the elements have been printed out, the loop finishes.

Here's the fiddle (you'll have to open the console in order to see the results). Hope it helps.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download