1

For example a 3x3 grid.

[ 1 ] [ 2 ] [ 3 ]
[ 4 ] [ 5 ] [ 6 ]
[ 7 ] [ 8 ] [ 9 ]

I need traverse the the grid in a cyclical manner and output each number where the path has been.

The input for a 3x3 grid is a multidimensional array:

input = [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9]
]

For a 3x3 grid the output should be an array or string.

output = [1, 2, 3, 6, 9, 8, 7, 4, 5]

The solution also needs to scale to any NxN grid.

I am looking for the solution of this programming problem. I have tried many different methods to do this but I can not seem to do it. I would love to learn how and also some bonus advice how I can improve my problem solving ability.

Millicano
  • 31
  • 5
  • 1
    Have you done any research at all? Take a look at http://stackoverflow.com/questions/398299/looping-in-a-spiral and one of the fiddles mentioned therein: http://jsfiddle.net/davidonet/HJQ4g/ – Snowmonkey Feb 01 '17 at 16:52
  • I guess spiral was the word I was looking for to search with. Would be nice if the solution could be explained more simply. – Millicano Feb 01 '17 at 17:24
  • 2
    Search google for 'nxn grid spiral algorithm javascript' -- won't find a LOT of javascript, but some are very well explained. For example, https://algorithmstuff.wordpress.com/2013/10/13/print-a-matrix-in-spiral-order/ – Snowmonkey Feb 01 '17 at 17:36
  • Thank you. I will check it out. – Millicano Feb 01 '17 at 17:48
  • Not gonna lie, kind of hurt my head. "I'm just a little black rain cloud..." – Snowmonkey Feb 01 '17 at 17:53
  • My input is also a multi dimensional array. Which I think is a bit more specific than those examples. I am going to look at the maths behind them and see if I can apply it to this. I have updated the Q. – Millicano Feb 01 '17 at 19:56
  • Possible duplicate of [Looping in a spiral](http://stackoverflow.com/questions/398299/looping-in-a-spiral) – Zong Feb 01 '17 at 20:20
  • Sorry I picked up on the spiral thing late. I've been writing way, way too much code lately. Starting to skip details, I need to hit the gym and have a beer ;p – Tim Consolazio Feb 01 '17 at 20:20

2 Answers2

1

Here is a possible solution using some recursion:

function traverseSpiral(n, level=0) {
  //USE A CURSOR TO TRAVERSE THE OUTERMOST LOOP FOR n
  var x=0;
  var y=0;
  //TOP
  while (x<n) {
    output.push(input[level+y][level+x]);
    x++;
  }
  x--;
  y++;
  //RIGHT
  while (y<n) {
    output.push(input[level+y][level+x]);
    y++;
  }
  y--;
  x--;
  //BOTTOM
  while (x>=0) {
    output.push(input[level+y][level+x]);
    x--;
  }
  x++;
  y--;
  //LEFT
  while (y>0) {
    output.push(input[level+y][level+x]);
    y--;
  }
  y++;
  //WE COMPLETED THE LOOP. NOW WE WE ARE LEFT WITH A GRID OF (N-2)x(N-2)
  n = n - 2;
  if (n>1) {
    //TRAVERSE THE NEXT LEVEL INNER LOOP
    return traverseSpiral(n,level+1);
  } else if (n==1) {
    //IF N=1 THEN THERE IS ONE SPACE LEFT. JUST GET THAT LAST SPACE AND WE'RE DONE.
    output.push(input[y][x+1]);
    return output;
  } else {
    //IF N=0 THEN WE ARE DONE.
    return output;
  }
}

Working samples:

4x4 https://jsfiddle.net/mspinks/4gaskn8o/19/

3x3 https://jsfiddle.net/mspinks/4gaskn8o/21/

Note: this works for NxN, as specified. It does not work for NxM.

Matt Spinks
  • 6,380
  • 3
  • 28
  • 47
  • Thank you. Would you be able to break it down and explain it? I would like to know what I could do to improve my ability to solve these problems. – Millicano Feb 02 '17 at 12:19
  • 1
    It's really a matter of being able to break these problems down into smaller problems. In the case of this spiral, you are repeating a pattern over and over again (start at the top, go down the right side, over and back up the left side). If you complete that process on the outermost "loop", then you are left with a smaller matrix ((N-2)x(N-2)). So you do the same thing again with N-2. Keep doing that until N=1 or N=0. – Matt Spinks Feb 02 '17 at 14:45
  • Basically my solution uses a cursor that traverses the outermost loop. Then recursion kicks in and the process is repeated on next inner loop. Recursion continues on deeper loops until N=1 or N=0. If N=1, then N started out as an odd number, and there is one space left in the middle. Get that one extra space and we are done. If N=0, then N started out as an even number and we are done. – Matt Spinks Feb 02 '17 at 14:49
  • I just added some additional comments that will hopefully help explain the process. – Matt Spinks Feb 02 '17 at 14:53
0

Here is the fiddle code

See the pattern.

If you get to limit of the array or to the previous position, then you have to either decrease/increase the column variable or row variable.

The pattern for cyclic looping is

  1. increase column variable ( j )
  2. increase row variable ( i )
  3. decrease column variable ( j )
  4. decrease row variable ( i )
  5. increase column variable ( j )
  6. increase row variable ( i ) .... ....

Here is my code

//input array
var input = [[1,2,3,4],[5,6,7,8],[9,10,11,12],[13,14,15,16]]

//get the no of rows
var noOfRows = input.length

//get the no of cols
var noOfCols = input[0].length

//initialize i and j to 0
var i =0, j = 0;

//first we go by increasing var j
var status = "increasingJ";

//output array initalize to empty array
var output = []

//till output is no equal to 9, loop through
while(output.length != noOfCols * noOfRows ){

    if(status == "increasingI"){
        
        if( input[i] == undefined || input[i][j] == null){
            i--;
            j--;
            status = "decreasingJ";     
        }else{
            output.push(input[i][j]);
            input[i][j] = null;
            i++;
        }
    }
    if(status == "increasingJ"){
        if( input[j] == undefined || input[i][j] == null){
        
            j--;
            i++;
            status = "increasingI";     
        }else{
            output.push(input[i][j]);
            input[i][j] = null;
            j++;
        }
    }
    if(status == "decreasingI"){
        if( input[i] == undefined || input[i][j] == null){
            i++;
            j++;
            status = "increasingJ";         
        }else{
            output.push(input[i][j]);
            input[i][j] = null;
            i--;
        }
    }
    if(status == "decreasingJ"){
        if( input[j] == undefined || input[i][j] == null){
            j++;
            i--;    
            status = "decreasingI";         
        }else{
            output.push(input[i][j]);
            input[i][j] = null;
            j--;
        }
    }
}
Community
  • 1
  • 1
Netdeamon
  • 175
  • 2
  • 3
  • 9