Algorithm for iterating over an outward spiral on a discrete 2D grid from the origin

前端 未结 12 1635
独厮守ぢ
独厮守ぢ 2020-12-05 06:54

For example, here is the shape of intended spiral (and each step of the iteration)

          y
          |
          |
   16 15 14 13 12
   17  4  3  2 11
--         


        
12条回答
  •  借酒劲吻你
    2020-12-05 07:25

    I've done pretty much the same thin as a training exercise, with some differences in the output and the spiral orientation, and with an extra requirement, that the functions spatial complexity has to be O(1).

    After think for a while I came to the idea that by knowing where does the spiral start and the position I was calculating the value for, I could simplify the problem by subtracting all the complete "circles" of the spiral, and then just calculate a simpler value.

    Here is my implementation of that algorithm in ruby:

    def print_spiral(n)
      (0...n).each do |y|
        (0...n).each do |x|
          printf("%02d ", get_value(x, y, n))
        end
        print "\n"
      end
    end
    
    
    def distance_to_border(x, y, n)
      [x, y, n - 1 - x, n - 1 - y].min
    end
    
    def get_value(x, y, n)
      dist = distance_to_border(x, y, n)
      initial = n * n - 1
    
      (0...dist).each do |i|
        initial -= 2 * (n - 2 * i) + 2 * (n - 2 * i - 2)
      end        
    
      x -= dist
      y -= dist
      n -= dist * 2
    
      if y == 0 then
        initial - x # If we are in the upper row
      elsif y == n - 1 then
        initial - n - (n - 2) - ((n - 1) - x) # If we are in the lower row
      elsif x == n - 1 then
        initial - n - y + 1# If we are in the right column
      else
        initial - 2 * n - (n - 2) - ((n - 1) - y - 1) # If we are in the left column
      end
    end
    
    print_spiral 5
    

    This is not exactly the thing you asked for, but I believe it'll help you to think your problem

提交回复
热议问题