Zig-zag scan an N x N array

前端 未结 8 2108
野的像风
野的像风 2021-01-30 08:32

I have a simple array. The array length always has a square root of an integer. So 16, 25, 36 etc.

$array = array(\'1\', \'2\', \'3\', \'4\' ... \'25\');
         


        
相关标签:
8条回答
  • 2021-01-30 09:19

    Example Python implementation:

    def wave(size):
        curX = 0
        curY = 0
        direction = "down"
        positions = []
        positions.append((curX, curY))
        while not (curX == size-1 and curY == size-1):
            if direction == "down":
                if curY == size-1: #can't move down any more; move right instead
                    curX += 1
                else:
                    curY += 1
                positions.append((curX, curY))
                #move diagonally up and right
                while curX < size-1 and curY > 0:
                    curX += 1
                    curY -= 1
                    positions.append((curX, curY))
                direction = "right"
                continue
            else: #direction == "right"
                if curX == size-1: #can't move right any more; move down instead
                    curY += 1
                else:
                    curX += 1
                positions.append((curX, curY))
                #move diagonally down and left
                while curY < size-1 and curX > 0:
                    curX -= 1
                    curY += 1
                    positions.append((curX, curY))
                direction = "down"
                continue
        return positions
    
    size = 5
    for x, y in wave(size):
        index = 1 + x + (y*size)
        print index, x, y
    

    Output:

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

    Comedy one line implementation:

    def wave(size):
        return [1+x+size*y for x,y in filter(lambda (x,y): x >=0 and x < size and y >= 0 and y < size, reduce(lambda x, y: x+y, [r if i==0 else list(reversed(r)) for i, r in enumerate([(x-delta, delta) for delta in range(size)] for x in range(size*2))], []))]
    
    print wave(5)
    

    output:

    [1, 6, 2, 11, 7, 3, 16, 12, 8, 4, 21, 17, 13, 9, 5, 22, 18, 14, 10, 23, 19, 15, 24, 20, 25]
    
    0 讨论(0)
  • 2021-01-30 09:27

    This is my take on it. Its similiar to qiuntus's response but more concise.

    function wave($base) {
      $i = 1;
      $a = $base;
      $square = $base*$base;
      $out = array(1);
    
      while ($i < $square) {
        if ($i > ($square - $base)) { // hit the bottom
          $i++;
          $out[] = $i;
          $a = 1 - $base;
        } elseif ($i % $base == 0) { // hit the right
          $i += $base;
          $out[] = $i;
          $a = $base - 1;
        } elseif (($i - 1) % $base == 0) { // hit the left
          $i += $base;
          $out[] = $i;
          $a = 1 - $base;
        } elseif ($i <= $base) { // hit the top
          $i++;
          $out[] = $i;
          $a = $base - 1;
        }
    
        if ($i < $square) {
          $i += $a;
          $out[] = $i;
        }
      }
    
      return $out;
    }
    
    0 讨论(0)
提交回复
热议问题