HiveBrain v1.2.0
Get Started
← Back to all entries
patternpythonMinor

Write a function to print numbers

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
numbersprintfunctionwrite

Problem

I would like to write a python or c++ function to print numbers like the following examples (with n as input parameter):

When n = 3, print:

1 2 3
8 0 4
7 6 5


When n = 4, print:

4  5  6  7
15 0  1  8
14 3  2  9
13 12 11 10


I have an answer in the following code block, but it is not quite elegant. Does anyone have a better solution?

def print_matrix(n):
  l = [i for i in range(0,n*n)]

  start = (n-1)/2
  end = n-1-start
  count = 0
  if start ==end:
    l [start+ n*end] = count
    start -= 1
    count +=1

  while start >=0:
        end = n - start
        for i in range(start, end-1):
                x= i
                y= start
                print y*n +x
                l[y*n +x] = count
                count +=1
        for i in range(start, end-1):
                x = end-1
                y = i
                print y*n +x
                l[y*n +x] = count
                count +=1
        for i in range(end-1,start,-1):
                x= i
                y= end-1
                print y*n +x
                l[y*n +x] = count
                count +=1
        for i in range(end-1, start,-1):
                x = start
                y = i
                print y*n +x
                l[y*n +x] = count
                count +=1
        start -=1

  print l

Solution

Using a 2D array to store the matrix, we can simplify the function greatly. This uses Python 2 syntax.

def print_matrix(n):
    mat = [[0]*n for _ in xrange(n)]

    k = 0 # value to write
    for level in reversed(xrange(n, 0, -2)):
        start = n/2 - level/2
        pr = pc = start # current row, column indices
        if level == 1: # special case: no perimeter crawl
            mat[pr][pc] = k
            k += 1
            continue
        # walk along each edge of the perimeter
        for dr, dc in [(0,1), (1,0), (0,-1), (-1,0)]:
            for i in xrange(level - 1):
                mat[pr][pc] = k
                k, pr, pc = k+1, pr+dr, pc+dc

    width = len(str(n*n-1))
    for i in mat:
        for j in i:
            print '{:<{width}}'.format(j, width=width),
        print


Samples:

>>> print_matrix(4)
4  5  6  7 
15 0  1  8 
14 3  2  9 
13 12 11 10
>>> print_matrix(3)
1 2 3
8 0 4
7 6 5
>>> print_matrix(2)
0 1
3 2
>>> print_matrix(1)
0
>>> print_matrix(9)
49 50 51 52 53 54 55 56 57
80 25 26 27 28 29 30 31 58
79 48 9  10 11 12 13 32 59
78 47 24 1  2  3  14 33 60
77 46 23 8  0  4  15 34 61
76 45 22 7  6  5  16 35 62
75 44 21 20 19 18 17 36 63
74 43 42 41 40 39 38 37 64
73 72 71 70 69 68 67 66 65

Code Snippets

def print_matrix(n):
    mat = [[0]*n for _ in xrange(n)]

    k = 0 # value to write
    for level in reversed(xrange(n, 0, -2)):
        start = n/2 - level/2
        pr = pc = start # current row, column indices
        if level == 1: # special case: no perimeter crawl
            mat[pr][pc] = k
            k += 1
            continue
        # walk along each edge of the perimeter
        for dr, dc in [(0,1), (1,0), (0,-1), (-1,0)]:
            for i in xrange(level - 1):
                mat[pr][pc] = k
                k, pr, pc = k+1, pr+dr, pc+dc

    width = len(str(n*n-1))
    for i in mat:
        for j in i:
            print '{:<{width}}'.format(j, width=width),
        print
>>> print_matrix(4)
4  5  6  7 
15 0  1  8 
14 3  2  9 
13 12 11 10
>>> print_matrix(3)
1 2 3
8 0 4
7 6 5
>>> print_matrix(2)
0 1
3 2
>>> print_matrix(1)
0
>>> print_matrix(9)
49 50 51 52 53 54 55 56 57
80 25 26 27 28 29 30 31 58
79 48 9  10 11 12 13 32 59
78 47 24 1  2  3  14 33 60
77 46 23 8  0  4  15 34 61
76 45 22 7  6  5  16 35 62
75 44 21 20 19 18 17 36 63
74 43 42 41 40 39 38 37 64
73 72 71 70 69 68 67 66 65

Context

StackExchange Code Review Q#16503, answer score: 5

Revisions (0)

No revisions yet.