Spiral matrix: Difference between revisions

From Rosetta Code
Content added Content deleted
(Fill array with a spiral of integers.)
 
No edit summary
Line 45: Line 45:
12 11 10 9 8
12 11 10 9 8
</pre>
</pre>

== Recursive Solution ==
<python>
def spiral_part(x,y,n):
if x==-1 and y==0:
return -1
if y==(x+1) and x<(n/2):
return spiral_part(x-1, y-1, n-1) + 4*(n-y)

if x<(n-y) and y<=x:
return spiral_part(y-1, y, n) + (x-y) + 1
if x>=(n-y) and y<=x:
return spiral_part(x, y-1, n) + 1
if x>=(n-y) and y>x:
return spiral_part(x+1, y, n) + 1
if x<(n-y) and y>x:
return spiral_part(x, y-1, n) - 1

def spiral(n):
array = [[None]*n for j in range(n)]
for x in range(n):
for y in range(n):
array[x][y] = spiral_part(x,y,n)
return array
</python>

Adding a cache for the ''spiral_part'' function it could be quite efficient.

Revision as of 10:40, 5 August 2008

Produce a spiral array. A spiral array is a square arrangement of the first N2 natural numbers, where the numbers increase sequentially as you go around the edges of the array spiralling inwards.

For example, given 5, produce this array:

 0  1  2  3  4
15 16 17 18  5
14 23 24 19  6
13 22 21 20  7
12 11 10  9  8

Python

<python> def spiral(n):

   dx,dy = 1,0            # Starting increments
   x,y = 0,0              # Starting location
   i = 0                  # starting value
   myarray = [[None]* n for j in range(n)]
   while i < n**2:
       myarray[x][y] = i
       i += 1
       nx,ny = x+dx, y+dy
       if 0<=nx<n and 0<=ny<n and myarray[nx][ny] == None:
           x,y = nx,ny
           continue
       else:
           dx,dy = (-dy,dx) if dy else (dy,dx)
           x,y = x+dx, y+dy
   return myarray

def printspiral(myarray):

   n = range(len(myarray))
   for y in n:
       for x in n:
           print "%2i" % myarray[x][y],
       print

printspiral(spiral(5)) </python> Sample output:

 0  1  2  3  4
15 16 17 18  5
14 23 24 19  6
13 22 21 20  7
12 11 10  9  8

Recursive Solution

<python> def spiral_part(x,y,n):

   if x==-1 and y==0:
       return -1
   if y==(x+1) and x<(n/2):
       return spiral_part(x-1, y-1, n-1) + 4*(n-y)
   if x<(n-y) and y<=x:
       return spiral_part(y-1, y, n) + (x-y) + 1
   if x>=(n-y) and y<=x:
       return spiral_part(x, y-1, n) + 1
   if x>=(n-y) and y>x:
       return spiral_part(x+1, y, n) + 1
   if x<(n-y) and y>x:
       return spiral_part(x, y-1, n) - 1

def spiral(n):

   array = [[None]*n for j in range(n)]
   for x in range(n):
       for y in range(n):
           array[x][y] = spiral_part(x,y,n)
   return array

</python>

Adding a cache for the spiral_part function it could be quite efficient.