2015-01-18

Spiral Matrix

Have you ever tried to assign integer values to a square matrix in spiral order? Eg. for a 5x5 matrix this would look as follows:

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

If this is what you have been lying wake at night for, here comes an iterative solution using Python/Numpy:

#!/usr/bin/env python
""" create a spiral array """

import numpy

def spiral(n):

     mat = numpy.zeros([n,n])

    dirs = [
        numpy.array([0,1]),  #right
        numpy.array([1,0]),  #down
        numpy.array([0,-1]), #left
        numpy.array([-1,0]), #up
    ]

    ptr = numpy.array([0,-1])
    ptr_prime = ptr
    cur_dir_ind = 0
    for i in range(1,n*n+1):
        #adjust direction if necessary
        while(True):
                ptr_prime = ptr + dirs[cur_dir_ind]

                if ptr_prime[0]<0 or ptr_prime[0]>=n or ptr_prime[1]<0 \\ 
                   or ptr_prime[1] >= n:
                        cur_dir_ind = (cur_dir_ind + 1) % len(dirs)
                elif mat[ptr_prime[0],ptr_prime[1]] > 0.0:
                        cur_dir_ind = (cur_dir_ind + 1) % len(dirs)
                else:
                    break

        #update ptr;
        ptr = ptr_prime
        mat[ptr[0],ptr[1]] = i
    
    return mat

2 comments:

  1. Or something like this? (replace underscores with whitespace)

    #!/usr/bin/env python
    import numpy as np

    # modified from a game of code golf​
    def f(h,w):
    _ _ n = np.ones((h, w))
    _ _ l = np.arange(1, h * w + 1)
    _ _ m = n
    _ _ i = 0
    _ _ while True:
    _ _ _ _ try:
    _ _ _ _ _ _ s = m.shape[1]
    _ _ _ _ _ _ m[0, :] = l[i:i + s]
    _ _ _ _ _ _ i += s
    _ _ _ _ _ _ m = np.rot90(m[1:, :])
    _ _ _ _ except IndexError:
    _ _ _ _ _ _ break
    _ _ return n

    print f(6,7)

    ReplyDelete