Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
452 views
in Technique[技术] by (71.8m points)

ruby - Looping in a spiral outside-in

I'm looking to loop through a matrix similar to Looping in a spiral but looping outside-in, instead of inside-out. Can anyone help me with a good way to do this for a matrix of any size, ideally in Ruby?

Example: In a 3x4 matrix I want to start at [0,0] going right, then move down once I reach [3,0], move left at [3,2] etc.

[0,0] [1,0] [2,0] [3,0]
[0,1] [1,1] [2,1] [3,1]
[0,2] [1,2] [2,2] [3,2]

The order to move is shown below:

0  1  2  3
9  10 11 4
8  7  6  5

And the output would be:

[0,0], [1,0], [2,0], [3,0], [3,1], [3,2], [2,2], [1,2], [0,2], [0,1], [1,1], [2,1]
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Without loss of generality, let's write the array as:

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

The desired result is:

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

I will use a helper:

def rotate_anticlockwise(arr)
  arr.map(&:reverse).transpose
end

For example:

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

We can now compute the desired result as follows:

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] 

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...