Click here to Skip to main content
15,891,431 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
Hi CPs,
Its been a long time. And I'm stuck at an idea and I need your opinions or solutions to it. So here I go.

Lets consider a 4x4 matrix
|1  2  3  4  |
|5  6  7  8  |
|9  10 11 12 |
|13 14 15 16 |


In a spiral order it will be re-written as 1 2 3 4 8 12 16 15 14 13 9 5 6 7 11 10.

So how would my conditions go? I wrote a program for a 4x4 matrix but the IF-conditions has to be increased each time the matrix grows in size. And my input won't always be a square matrix. So how to make this dynamic?
Posted
Updated 4-Aug-14 10:08am
v2
Comments
PIEBALDconsult 4-Aug-14 15:26pm    
Oh, come on, how am I supposed to remember something I wrote thirty years ago? Well, OK, I have it written down in my BASICplus book from high school. :D
Except mine was to display the content of a matrix on a VT100 screen and I wanted to do something more interesting than left-to-right, top-to-bottom.

As I recall I had a number of for/next loops -- one to go across the top, one to go down the right, one to go across the bottom, one to go up the left, and repeat.

Sorry I didn't get back to you earlier. Wondering what came of this.

Here's what I devised:

C#
public static partial class Array
{
  public static System.Collections.Generic.IEnumerable<T>
  Spiral<T>
  (
    this T[,] Matrix
  )
  {
    int top = Matrix.GetLowerBound ( 0 )
      , bot = Matrix.GetUpperBound ( 0 )
      , lft = Matrix.GetLowerBound ( 1 )
      , rgt = Matrix.GetUpperBound ( 1 ) ;

    while ( top <= bot )
    {
      for ( int i = lft ; i <= rgt ; i++ ) yield return ( Matrix [ top ,   i ] ) ;
      top++ ;

      for ( int i = top ; i <= bot ; i++ ) yield return ( Matrix [   i , rgt ] ) ;
      rgt-- ;

      for ( int i = rgt ; i >= lft ; i-- ) yield return ( Matrix [ bot ,   i ] ) ;
      bot-- ;

      for ( int i = bot ; i >= top ; i-- ) yield return ( Matrix [   i , lft ] ) ;
      lft++ ;
    }

    yield break ;
  }
}
 
Share this answer
 
Comments
BillWoodruff 22-Dec-14 23:36pm    
+5 this is fascinating code !
How about doing it this way: Your spiral is nothing but nested rectangles. The outer rectangle starts at (0,0), the next inner one at (1,1), and so forth until you reach (width+1)/2; (note the +1 to cater for odd widths).

So I would create an outer loop for that, say
C++
int i;
int cntRects = (width + 1) / 2;

for (i = 0; i < cntRects; ++i)
{
    ...


Inside that outer loop you do four inner loops for the four sides of the rectangle, i.e. top, right, bottom, left. You can construct the indices easily from i, width and height. Here I am going to do the first one for you:
C++
int x, y;

// top side
y = i;
for (x = i; x < width - i; ++i)
    AddPoint (x, y);

...
 
Share this answer
 
Comments
Usman Hunjra 13-Aug-14 3:39am    
+5 && Respect ++
nv3 13-Aug-14 4:39am    
Thanks!
You could create a bookkeeping matrix, say 'visited', with visited[j][k]=1 if the same item in the original matrix has been visited. Now suppose you are proceeding on the positive x-axis, then if visited[y][x+1] == 1 (or x == N-1, that is you are on a boundary) then you have to change direction (in this example, you have to go down).
 
Share this answer
 
v2
Wow thank you everyone for replying.

I am using C to do the task. So I cant use the class and other functions :)

But I get the idea. Thank you very much.
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900