从外面盘旋

ant*_*ant 5 ruby algorithm spiral

我希望循环一个类似于循环的矩阵,但是从外向内循环,而不是从里到外循环.任何人都可以帮助我为任何大小的矩阵做一个好的方法,理想情况下在Ruby中吗?

示例:在3x4矩阵中,我想从[0,0]向右开始,然后在达到[3,0]时向下移动,在[3,2]处向左移动等.

[0,0] [1,0] [2,0] [3,0]
[0,1] [1,1] [2,1] [3,1]
[0,2] [1,2] [2,2] [3,2]
Run Code Online (Sandbox Code Playgroud)

移动顺序如下所示:

0  1  2  3
9  10 11 4
8  7  6  5
Run Code Online (Sandbox Code Playgroud)

输出将是:

[0,0], [1,0], [2,0], [3,0], [3,1], [3,2], [2,2], [1,2], [0,2], [0,1], [1,1], [2,1]
Run Code Online (Sandbox Code Playgroud)

Car*_*and 10

不失一般性,让我们把数组写成:

arr = [
  [ 1,  2,  3, 4,],
  [12, 13, 14, 5,],
  [11, 16, 15, 6,],
  [10,  9,  8, 7,]
]
Run Code Online (Sandbox Code Playgroud)

期望的结果是:

[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]
Run Code Online (Sandbox Code Playgroud)

我会用一个帮手:

def rotate_anticlockwise(arr)
  arr.map(&:reverse).transpose
end
Run Code Online (Sandbox Code Playgroud)

例如:

rotate_anticlockwise(arr)
  #=> [[4,  5,  6, 7],
  #    [3, 14, 15, 8],
  #    [2, 13, 16, 9],
  #    [1, 12, 11, 10]] 
Run Code Online (Sandbox Code Playgroud)

我们现在可以按如下方式计算所需的结果:

out = []
a = arr.map(&:dup)
while a.any?
  out.concat(a.shift)
  a = rotate_anticlockwise(a)
end
out
  # => [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16] 
Run Code Online (Sandbox Code Playgroud)


O-I*_*O-I 5

这个问题一直令我着迷.@CarySwoveland的诀窍让它在Ruby中非常优雅.这是一个单行方法:

def spiral(matrix)
  matrix.empty? ? [] : matrix.shift + spiral(matrix.transpose.reverse)
end

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

spiral(arr)

# => [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]
Run Code Online (Sandbox Code Playgroud)

然而,这种方法的一个缺陷是它会改变原始矩阵arr:

arr

# => [[12, 13, 14, 5], [11, 16, 15, 6], [10, 9, 8, 7]]
Run Code Online (Sandbox Code Playgroud)

这个要点有几个答案值得一看.