square puzzle solution

前端 未结 5 954
一生所求
一生所求 2021-01-01 02:51

Question: given an integer number n, print the numbers from 1 up to n2 like this:

n = 4

result is:

01 02 03 04
12 13 14 05
11 16 1         


        
5条回答
  •  说谎
    说谎 (楼主)
    2021-01-01 03:23

    Here's a different approach. It relies on spotting that the movements you make cycle between: right, down, left, up, right, .... Further, the number of times you move goes: 3 right, 3 down, 3 left, 2 up, 2 right, 1 down, 1 left. So without further ado, I will code this up in Python.

    First, I will use some itertools and some numpy:

    from itertools import chain, cycle, imap, izip, repeat
    from numpy import array
    

    The directions cycle between: right, down, left, up, right, ...:

    directions = cycle(array(v) for v in ((0,1),(1,0),(0,-1),(-1,0)))
    

    (I'm using numpy's arrays here so I can easily add directions together. Tuples don't add nicely.)

    Next, the number of times I move counts down from n-1 to 1, repeating each number twice, and the first number three times:

    countdown = chain((n-1,), *imap(repeat, range(n-1,0,-1), repeat(2)))
    

    So now my sequence of directions can be created by repeating each successive direction by the paired number in countdown:

    dirseq = chain(*imap(repeat, directions, countdown))
    

    To get my sequence of indices, I can just sum this sequence, but (AFAIK) Python does not provide such a method, so let's quickly throw one together:

    def sumseq(seq, start=0):
      v = start
      yield v
      for s in seq:
        v += s
        yield v
    

    Now to generate the original array, I can do the following:

    a = array(((0,)*n,)*n) # n-by-n array of zeroes
    for i, v in enumerate(sumseq(dirseq, array((0,0)))):
      a[v[0], v[1]] = i+1
    print a
    

    Which, for n = 4, gives:

    [[ 1  2  3  4]
     [12 13 14  5]
     [11 16 15  6]
     [10  9  8  7]]
    

    and, for n = 5, gives:

    [[ 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]]
    

    This approach can be generalised to rectangular grids; I leave this as an exercise for the reader ;)

提交回复
热议问题