给出2D矩阵:
matrix = [
[ 1, 2, 3, 4 ],
[ 5, 6, 7, 8 ],
[ 9, 10, 11, 12 ],
[ 13, 14, 15, 16 ]
]
我们如何逆时针旋转矩阵,以便像这样推动值?
matrix = [
[ 2, 3, 4, 8 ]
[ 1, 7, 11, 12 ]
[ 5, 6, 10, 16 ]
[ 9, 13, 14, 15 ]
]
这个问题不是this
和this
的重复,因为我要达到的目的是通过逆时针旋转值。
我当前的实现仅以逆时针方式打印出这些值,但不会旋转这些值。
layers = [_rows, _cols].min / 2
r1, r2, c3, c4 = 0, _rows, _cols, _cols
new_matrix = Array.new(_rows + 1) { Array.new(_cols + 1) }
(0..layers).each do |layer|
row_top_left, row_bottom_left, col_top_right, col_bottom_right = r1, r2, c3, c4
result = []
while row_top_left < row_bottom_left
result << matrix[row_top_left][layer]
row_top_left += 1
end
row_bottom_left = layer
while row_bottom_left < col_bottom_right
result << matrix[row_top_left][row_bottom_left]
row_bottom_left += 1
end
temp_col_bottom_right = col_bottom_right
temp_col_top_right = layer
while col_bottom_right > temp_col_top_right
result << matrix[col_bottom_right][temp_col_bottom_right]
col_bottom_right -= 1
end
# p row_top_left
tmp_row_top_left = layer
while col_top_right > tmp_row_top_left
result << matrix[tmp_row_top_left][col_top_right]
col_top_right -= 1
end
p result.cycle
r1 += 1
r2 -= 1
c3 -= 1
c4 -= 1
关键思想是矩阵需要以正确的方式旋转。例如,假设我们的矩阵需要旋转2次。因此:
matrix_rotation(
matrix.length - 1, # rows
matrix[0].length - 1, # columns
2, # Nom. of rotation
matrix # The matrix
)
matrix = [
# Original Iter: 1 Iter: 2
[ 1, 2, 3, 4 ], # [ 2, 3, 4, 8 ] # [ 3, 4, 8, 12 ]
[ 5, 6, 7, 8 ], # [ 1, 7, 11, 12 ] # [ 2, 11, 10, 16 ]
[ 9, 10, 11, 12 ], # [ 5, 6, 10, 16 ] # [ 1, 7, 6, 15 ]
[ 13, 14, 15, 16 ] # [ 9, 13, 14, 15 ] # [ 5, 9, 13, 14 ]
]
数组的维数表示为:NxM
,其中N和M可以是任何数字,偶数或奇数。例如5x4、4、4、4x8等。
没有“空方格”之类的东西。
答案 0 :(得分:3)
代码
def nxt(rows, cols, row, col)
case row
when rows[:first]
col == cols[:last] ? [row+1, col] : [row, col+1]
when rows[:last]
col == cols[:first] ? [row-1, col] : [row, col-1]
else
col == cols[:last] ? [row+1, col] : [row-1, col]
end
end
def rotate_array_times(matrix, n)
arr = matrix.dup.map(&:dup)
nrows, ncols = arr.size, arr.first.size
0.upto([nrows, ncols].min/2-1) do |m|
rows = { first: m, last: nrows-m-1 }
cols = { first: m, last: ncols-m-1 }
rect_size = 2 * (nrows + ncols) - 8*m - 4
rotations = n % rect_size
row = col = rrow = rcol = m
rotations.times { rrow, rcol = nxt(rows, cols, rrow, rcol) }
rect_size.times do
arr[row][col] = matrix[rrow][rcol]
row, col = nxt(rows, cols, row, col)
rrow, rcol = nxt(rows, cols, rrow, rcol)
end
end
arr
end
示例
matrix = [
[ 1, 2, 3, 4],
[ 5, 6, 7, 8],
[ 9, 10, 11, 12],
[13, 14, 15, 16]
]
(1..3).each { |n| p rotate_array_times(matrix, n) }
[[2, 3, 4, 8],
[1, 7, 11, 12],
[5, 6, 10, 16],
[9, 13, 14, 15]]
[[3, 4, 8, 12],
[2, 11, 10, 16],
[1, 7, 6, 15],
[5, 9, 13, 14]]
[[4, 8, 12, 16],
[3, 10, 6, 15],
[2, 11, 7, 14],
[1, 5, 9, 13]]
matrix = (1..24).each_slice(4).to_a
#=> [[ 1, 2, 3, 4],
# [ 5, 6, 7, 8],
# [ 9, 10, 11, 12],
# [13, 14, 15, 16],
# [17, 18, 19, 20],
# [21, 22, 23, 24]]
(1..3).each { |n| p rotate_array_times(matrix, n) }
#=> [[ 2, 3, 4, 8],
# [ 1, 7, 11, 12],
# [ 5, 6, 15, 16],
# [ 9, 10, 19, 20],
# [13, 14, 18, 24],
# [17, 21, 22, 23]]
# [[ 3, 4, 8, 12],
# [ 2, 11, 15, 16],
# [ 1, 7, 19, 20],
# [ 5, 6, 18, 24],
# [ 9, 10, 14, 23],
# [13, 17, 21, 22]]
# [[ 4, 8, 12, 16],
# [ 3, 15, 19, 20],
# [ 2, 11, 18, 24],
# [ 1, 7, 14, 23],
# [ 5, 6, 10, 22],
# [ 9, 13, 17, 21]]
matrix = (1..48).each_slice(8).to_a
#=> [[ 1, 2, 3, 4, 5, 6, 7, 8],
# [ 9, 10, 11, 12, 13, 14, 15, 16],
# [17, 18, 19, 20, 21, 22, 23, 24],
# [25, 26, 27, 28, 29, 30, 31, 32],
# [33, 34, 35, 36, 37, 38, 39, 40],
# [41, 42, 43, 44, 45, 46, 47, 48]]
(1..3).each { |n| p rotate_array_times(matrix, n) }
[[ 2, 3, 4, 5, 6, 7, 8, 16],
[ 1, 11, 12, 13, 14, 15, 23, 24],
[ 9, 10, 20, 21, 22, 30, 31, 32],
[17, 18, 19, 27, 28, 29, 39, 40],
[25, 26, 34, 35, 36, 37, 38, 48],
[33, 41, 42, 43, 44, 45, 46, 47]]
[[ 3, 4, 5, 6, 7, 8, 16, 24],
[ 2, 12, 13, 14, 15, 23, 31, 32],
[ 1, 11, 21, 22, 30, 29, 39, 40],
[ 9, 10, 20, 19, 27, 28, 38, 48],
[17, 18, 26, 34, 35, 36, 37, 47],
[25, 33, 41, 42, 43, 44, 45, 46]]
[[ 4, 5, 6, 7, 8, 16, 24, 32],
[ 3, 13, 14, 15, 23, 31, 39, 40],
[ 2, 12, 22, 30, 29, 28, 38, 48],
[ 1, 11, 21, 20, 19, 27, 37, 47],
[ 9, 10, 18, 26, 34, 35, 36, 46],
[17, 25, 33, 41, 42, 43, 44, 45]]
说明
nxt
给出行索引和列索引row
和col
,nxt(rows, cols, row, col)
返回子数组周边上“ next”元素的索引[next_row, next_col]
,以替换一次迭代中位于索引[row, col]
上的元素(也在周界上)。子数组由散列rows
和cols
给出,它们分别具有键:first
和:last
。
让我们考虑一个包含4个元素(行)的数组arr
,每个元素(行)具有6个值(列)。然后
nrows, ncols = arr.size, arr.first.size
#=> [4, 6]
如果m = 0
rows = { first: m, last: nrows-m-1 }
#=> {:first=>0, :last=>3}
cols = { first: m, last: ncols-m-1 }
#=> {:first=>0, :last=>5}
可以看到rows
和cols
描述了数组matrix
的“周长”。我们可以看到nxt
的工作方式如下。
first_row, first_col = rows[:first], cols[:first]
row, col = first_row, first_col
print "[#{row}, #{col}]"
loop do
next_row, next_col = nxt(rows, cols, row, col)
print "->[#{next_row}, #{next_col}]"
row, col = next_row, next_col
(puts; break) if [row, col] == [first_row, first_col]
end
[0, 0]->[0, 1]->[0, 2]->[0, 3]->[0, 4]->[0, 5]->[1, 5]->[2, 5]->[3, 5]->
[3, 4]->[3, 3]->[3, 2]->[3, 1]->[3, 0]->[2, 0]->[1, 0]->[0, 0]
如果m = 1
,则上述计算得出
[1, 1]->[1, 2]->[1, 3]->[1, 4]->[2, 4]->[2, 3]->[2, 2]->[2, 1]->[1, 1]
rotate_array_times
此方法构造matrix
,arrr
的深层副本,其元素按规定的次数旋转n
次,然后返回结果数组。
为了加快计算速度,n
被其自身的模数代替。例如,对于4x4数组,经过12次迭代后,数组的周长将恢复为其原始值。因此,执行n % 12
旋转就足够了。
matrix
包含n = [matrix.size, matrix.first.size].min
个子阵列,其周长将被旋转。每个子数组的左上角由坐标[m,m]
给出,其中m = 0..n-1
。
对于m
指定的子数组,第一步是确定matrix
元素的位置,以替换arr
上[m,m]
的元素。这是在行中完成的
rotations.times { rrow, rcol = nxt(rows, cols, rrow, rcol) }
(“ {replacement row”和“ replacement col”分别为"rrow"
和"rcol"
)。此时,arr
和{{1}给定的位置row #=> m
,col #=> m
的元素将被替换matrix
的元素}}。然后,执行以下操作的次数与子数组周边中要旋转的元素的次数相同:
rrow
调整效率
通过更换生产线可以实现效率的适度提高
rcol
使用
arr[row][col] = matrix[rrow][rcol]
row, col = nxt(rows, cols, row, col)
rrow, rcol = nxt(rows, cols, rrow, rcol)
并添加以下方法。
rotations.times { rrow, rcol = nxt(rows, cols, rrow, rcol) }
答案 1 :(得分:2)
如果您想直接跳至解决方案代码,请跳至此答案的底部。
您需要分解问题并独立解决每个问题。
让我们分别浏览每个点:
您需要一种获取层数的方法。下面的矩阵有2层。怎么样?
给出一个矩阵:
matrix layers
--------------------------------
| 1, 2, 3, 4 | 0 0 0 0 |
| 5, 6, 7, 8 | 0 1 1 0 |
| 9, 10, 11, 12 | 0 1 1 0 |
| 13, 14, 15, 16 | 0 0 0 0 |
--------------------------------
要查找层数,只需执行以下操作:
[rows, cols].min / 2
第一个问题就解决了。
这部分需要很多思考。让我们可视化:
matrix layers
--------------------------------
| 1, 2, 3, 4 | ↓ ← ← ↰ | 0 0 0 0 |
| 5, 6, 7, 8 | ↓ 1 1 ↑ | 0 ↓ ↰ 0 |
| 9, 10, 11, 12 | ↓ 1 1 ↑ | 0 ↳ → 0 |
| 13, 14, 15, 16 | ↳ → → → | 0 0 0 0 |
--------------------------------
这是可以实现的。我们将有4个for
循环。每个循环将照顾:
在进入循环之前,我们需要一些容器以螺旋形式存储我们的值。
让我们有一个临时数组来存储值:
# this array will get us the output of borders of the layer
row = []
为便于说明,让我们仅在最外层工作。 (即第0层:
# this loop will output the top-left side of the matrix
# ==============================
# ↓ [ 1, 2, 3, 4 ]
# ↓ [ 5, 6, 7, 8 ]
# ↓ [ 9, 10, 11, 12 ]
# ↓ [ 13, 14, 15, 16 ]
# Output: [[1, 5, 9], [6] ]
# ==============================
(0...rows - 1 - layer).each do |i|
row << matrix[i][layer]
end
注意: 0
表示第0层。
# this loop will output the bottom side of the matrix
# ==============================
# ↓ [ 1, 2, 3, 4 ]
# ↓ [ 5, 6, 7, 8 ]
# ↓ [ 9, 10, 11, 12 ]
# ↓ [ 13, 14, 15, 16 ]
# ↪ → → → →
# Output: [[1, 5, 9, 13, 14, 15], [6, 10]]
# ==============================
(0...cols - 1 - layer).each do |i|
row << matrix[rows - 1 - layer][i]
end
# this loop will output the right side of the matrix
# ==============================
# ↓ [ 1, 2, 3, 4 ] ↑
# ↓ [ 5, 6, 7, 8 ] ↑
# ↓ [ 9, 10, 11, 12 ] ↑
# [ 13, 14, 15, 16 ] ↑
# ↪ → → → → ⤻
# Output: [[1, 5, 9, 13, 14, 15, 16, 12, 8], [6, 10, 11]]
# ==============================
(rows - 1 - layer).step(0 + 1, -1).each do |i|
row << matrix[i][cols - 1 - layer]
end
# this loop will output the top side of the matrix
# ==============================
# ← ← ← ← ↰
# ↓ [ 1, 2, 3, 4 ] ↑
# ↓ [ 5, 6, 7, 8 ] ↑
# ↓ [ 9, 10, 11, 12 ] ↑
# [ 13, 14, 15, 16 ] ↑
# ↪ → → → → ⤻
# Output: [[1, 5, 9, 13, 14, 15, 16, 12, 8, 4, 3, 2], [6, 10, 11, 7]]
# ==============================
(cols - 1 - layer).step(0 + 1, -1).each do |i|
row << matrix[layer][i]
end
因此,在这一点上,我们具有螺旋形式的值。但是,此问题的最重要方面在于此部分。一个如何改变价值?有趣的是,我们将使用模数。
模将在这里起主要作用。这将使我们能够基于旋转来移动值。还要在数组中给我们正确的索引以开始移位。例如,如果我们要旋转2次:最外层为2%12 = 2。
# row = [1, 5, 9, 13, 14, 15, 16, 12, 8, 4, 3, 2]
shift = rotate % row.size
# if we negate shift variable, we can get correct index
# i.e. row[-2] = 3
idx = -shift
在移动值之前,让我们创建另一个包含正确值的矩阵:
# let us create a new matrix
result = (1..( rows * cols )).each_slice(rows).to_a
我们将以相同的方式再次循环,但是从row
中的idx获取值。例如:
(0...rows - 1 - 0).each do |i|
result[i][layer] = row[idx]
idx += 1
idx %= row.size
end
(0...cols - 1 - 0).each do |i|
result[rows - 1 - 0][i] = row[idx]
idx += 1
idx %= row.size
end
(rows - 1 - 0).step(0 + 1, -1).each do |i|
result[i][cols - 1 - 0] = row[idx]
idx += 1
idx %= row.size
end
(cols - 1 - 0).step(0 + 1, -1).each do |i|
result[0][i] = row[idx]
idx += 1
idx %= row.size
end
注意: 0
是第0层(为便于说明)
matrix_4_x_4 = (1..16).each_slice(4).to_a
matrix_8_x_8 = (1..64).each_slice(8).to_a
def matrix_rotation(*args)
# let us extract rows & cols from our matrix. We also need to know how
# times to rotate.
rows, cols, rotate, matrix = args
# to find out how many layers our matrix have, simply get the min of the two (rows, cols)
# and divide it
layers, str_cols = [rows, cols].min / 2, ""
# needed to beatify our console output in table format
cols.times do str_cols << "%5s " end
# we will work on a temporary array
temp_rows = []
# so the first task is to loop n times, where n is the number of layers
(0...layers).each do |layer|
# this array will get us the output of borders of the layer
row = []
# this loop will output the top-left side of the matrix
# ==============================
# ↓ [ 1, 2, 3, 4 ]
# ↓ [ 5, 6, 7, 8 ]
# ↓ [ 9, 10, 11, 12 ]
# ↓ [ 13, 14, 15, 16 ]
# Output: [[1, 5, 9], [6] ]
# ==============================
(layer...rows - 1 - layer).each do |i|
row << matrix[i][layer]
end
# this loop will output the bottom side of the matrix
# ==============================
# ↓ [ 1, 2, 3, 4 ]
# ↓ [ 5, 6, 7, 8 ]
# ↓ [ 9, 10, 11, 12 ]
# ↓ [ 13, 14, 15, 16 ]
# ↪ → → → →
# Output: [[1, 5, 9, 13, 14, 15], [6, 10]]
# ==============================
(layer...cols - 1 - layer).each do |i|
row << matrix[rows - 1 - layer][i]
end
# this loop will output the right side of the matrix
# ==============================
# ↓ [ 1, 2, 3, 4 ] ↑
# ↓ [ 5, 6, 7, 8 ] ↑
# ↓ [ 9, 10, 11, 12 ] ↑
# [ 13, 14, 15, 16 ] ↑
# ↪ → → → → ⤻
# Output: [[1, 5, 9, 13, 14, 15, 16, 12, 8], [6, 10, 11]]
# ==============================
(rows - 1 - layer).step(layer + 1, -1).each do |i|
row << matrix[i][cols - 1 - layer]
end
# this loop will output the top side of the matrix
# ==============================
# ← ← ← ← ↰
# ↓ [ 1, 2, 3, 4 ] ↑
# ↓ [ 5, 6, 7, 8 ] ↑
# ↓ [ 9, 10, 11, 12 ] ↑
# [ 13, 14, 15, 16 ] ↑
# ↪ → → → → ⤻
# Output: [[1, 5, 9, 13, 14, 15, 16, 12, 8, 4, 3, 2], [6, 10, 11, 7]]
# ==============================
(cols - 1 - layer).step(layer + 1, -1).each do |i|
row << matrix[layer][i]
end
temp_rows << row
end
# let us create a new matrix
result = (1..( rows * cols )).each_slice(rows).to_a
# we're going to loop in the same manner as before
(0...layers).each do |layer|
# based on current layer, get the values around that layer
row = temp_rows[layer]
# !important: the modulo will do the main thing here:
# It will allow us to shift values based on the rotate. But also
# gives us the correct index in the array to start the shift.
# For example, if we want to rotate 2 times: 2 % 12 = 2 for the outer most layer
shift = rotate % row.size
# when whe negate the shift value, we will get the correct index from the end of the array.
# row = [1, 5, 9, 13, 14, 15, 16, 12, 8, 4, 3, 2]
# So -2 in row[-2] for the outer layer is 3. We increment idx, then row[-1] is 2 etc..
idx = -shift
(layer...rows - 1 - layer).each do |i|
result[i][layer] = row[idx]
idx += 1
idx %= row.size
end
(layer...cols - 1 - layer).each do |i|
result[rows - 1 - layer][i] = row[idx]
idx += 1
idx %= row.size
end
(rows - 1 - layer).step(layer + 1, -1).each do |i|
result[i][cols - 1 - layer] = row[idx]
idx += 1
idx %= row.size
end
(cols - 1 - layer).step(layer + 1, -1).each do |i|
result[layer][i] = row[idx]
idx += 1
idx %= row.size
end
end
result.each do |row| printf("#{str_cols}\n", *row) end
end
matrix_rotation(
matrix_8_x_8.size,
matrix_8_x_8.first.size,
2,
matrix_8_x_8
)
答案 2 :(得分:0)
这是另一种实现方式(我没有创建方法,只是需要改进的逻辑)。
array = (1..24).each_slice(6).to_a
array.each { |e| p e }
puts
n = 4 # sub matrix rows
m = 6 # sub matrix cols
x = 0 # x row origin (corner) of the rotation
y = 0 # y col origin (corner) of the rotation
rotations = 2 # negative is ccw, positive is cw
raise "Sub matrix too small, must be 2x2 at least" if m < 2 || n < 2
# to add: check if the submatrix is inside the matrix, given the origin x, y
y_size = array.size
x_size = array.size
idx_map = Array.new(n){ [] }
m.times.map { |mm| n.times.map { |nn| idx_map[nn][mm] = [nn + x, mm + y] } }
before = [(idx_map.map(&:shift)).concat(idx_map.pop).concat(idx_map.map(&:pop).reverse).concat(idx_map.shift.reverse)].flatten(1)
after = before.rotate(rotations)
tmp = array.map(&:dup)
before.size.times.map { |idx| array[before[idx][0]][before[idx][1]] = tmp[after[idx][0]][after[idx][1]]}
array.each { |e| p e }
#=> [1, 2, 3, 4, 5, 6]
#=> [7, 8, 9, 10, 11, 12]
#=> [13, 14, 15, 16, 17, 18]
#=> [19, 20, 21, 22, 23, 24]
#=>
#=> [13, 7, 1, 2, 3, 4]
#=> [19, 8, 9, 10, 11, 5]
#=> [20, 14, 15, 16, 17, 6]
#=> [21, 22, 23, 24, 18, 12]
您还可以旋转从(1,1)开始的3x3子矩阵,例如n = 3
,m = 3
,x = 1
,y = 1
和{{ 1}}:
rotations = -1
答案 3 :(得分:0)
我认为将我的代码与@Humbledore的代码进行基准测试会很有趣。 (@iGian:如果您可以编辑答案以将其包装到带有参数matrix
和nbr_rotations
的方法中,则可以将您的代码添加到基准测试中。)
def nxt(rows, cols, row, col)
case row
when rows[:first]
col == cols[:last] ? [row+1, col] : [row, col+1]
when rows[:last]
col == cols[:first] ? [row-1, col] : [row, col-1]
else
col == cols[:last] ? [row+1, col] : [row-1, col]
end
end
def cary1(matrix, n)
arr = matrix.dup.map(&:dup)
nrows, ncols = arr.size, arr.first.size
0.upto([nrows, ncols].min/2-1) do |m|
rows = { first: m, last: nrows-m-1 }
cols = { first: m, last: ncols-m-1 }
rect_size = 2 * (nrows + ncols) - 8*m - 4
rotations = n % rect_size
row = col = rrow = rcol = m
rotations.times { rrow, rcol = nxt(rows, cols, rrow, rcol) }
rect_size.times do
arr[row][col] = matrix[rrow][rcol]
row, col = nxt(rows, cols, row, col)
rrow, rcol = nxt(rows, cols, rrow, rcol)
end
end
arr
end
def first_replacement_loc(rows, cols, rotations)
ncm1 = cols[:last]-cols[:first]
nrm1 = rows[:last]-rows[:first]
return [rows[:first], cols[:first]+rotations] if rotations <= ncm1
rotations -= ncm1
return [rows[:first]+rotations, cols[:last]] if rotations <= nrm1
rotations -= nrm1
return [rows[:last], cols[:last]-rotations] if rotations <= ncm1
rotations -= ncm1
[rows[:last]-rotations, cols[:first]]
end
def cary2(matrix, n)
arr = matrix.dup.map(&:dup)
nrows, ncols = arr.size, arr.first.size
0.upto([nrows, ncols].min/2-1) do |m|
rows = { first: m, last: nrows-m-1 }
cols = { first: m, last: ncols-m-1 }
rect_size = 2 * (nrows + ncols) - 8*m - 4
rotations = n % rect_size
row = col = m
rrow, rcol = first_replacement_loc(rows, cols, rotations)
rect_size.times do
arr[row][col] = matrix[rrow][rcol]
row, col = nxt(rows, cols, row, col)
rrow, rcol = nxt(rows, cols, rrow, rcol)
end
end
arr
end
def humbledore(matrix, rotate)
rows, cols = matrix.size, matrix.first.size
layers, str_cols = [rows, cols].min / 2, ""
# cols.times do str_cols << "%5s " end
temp_rows = []
(0...layers).each do |layer|
row = []
(layer...rows - 1 - layer).each do |i|
row << matrix[i][layer]
end
(layer...cols - 1 - layer).each do |i|
row << matrix[rows - 1 - layer][i]
end
(rows - 1 - layer).step(layer + 1, -1).each do |i|
row << matrix[i][cols - 1 - layer]
end
(cols - 1 - layer).step(layer + 1, -1).each do |i|
row << matrix[layer][i]
end
temp_rows << row
end
result = (1..( rows * cols )).each_slice(rows).to_a
(0...layers).each do |layer|
row = temp_rows[layer]
shift = rotate % row.size
idx = -shift
(layer...rows - 1 - layer).each do |i|
result[i][layer] = row[idx]
idx += 1
idx %= row.size
end
(layer...cols - 1 - layer).each do |i|
result[rows - 1 - layer][i] = row[idx]
idx += 1
idx %= row.size
end
(rows - 1 - layer).step(layer + 1, -1).each do |i|
result[i][cols - 1 - layer] = row[idx]
idx += 1
idx %= row.size
end
(cols - 1 - layer).step(layer + 1, -1).each do |i|
result[layer][i] = row[idx]
idx += 1
idx %= row.size
end
end
result
end
require 'benchmark'
def test(rows, cols, rotations)
puts "\nrows = #{rows}, cols = #{cols}, rotations = #{rotations}"
matrix = (1..rows*cols).each_slice(cols).to_a
Benchmark.bm do |x|
x.report("Cary1") { cary1(matrix, rotations) }
x.report("Cary2") { cary2(matrix, rotations) }
x.report("Humbledore") { humbledore(matrix, rotations) }
end
end
test 10,10,1
rows = 10, cols = 10, rotations = 1
user system total real
Cary1 0.000000 0.000000 0.000000 ( 0.000077)
Cary2 0.000000 0.000000 0.000000 ( 0.000074)
Humbledore 0.000000 0.000000 0.000000 ( 0.000051)
test 10,10,78
rows = 10, cols = 10, rotations = 78
user system total real
Cary1 0.000000 0.000000 0.000000 ( 0.000079)
Cary2 0.000000 0.000000 0.000000 ( 0.000061)
Humbledore 0.000000 0.000000 0.000000 ( 0.000053)
test 100,100,378
rows = 100, cols = 100, rotations = 378
user system total real
Cary1 0.000000 0.000000 0.000000 ( 0.007673)
Cary2 0.015625 0.000000 0.015625 ( 0.005168)
Humbledore 0.000000 0.000000 0.000000 ( 0.002919)
test 500,500,1950
rows = 500, cols = 500, rotations = 1950
user system total real
Cary1 0.171875 0.000000 0.171875 ( 0.166671)
Cary2 0.140625 0.000000 0.140625 ( 0.137141)
Humbledore 0.046875 0.000000 0.046875 ( 0.053705)
test 500,1000,2950
rows = 500, cols = 1000, rotations = 2950
user system total real
Cary1 0.296875 0.000000 0.296875 ( 0.292997)
Cary2 0.234375 0.000000 0.234375 ( 0.248384)
Humbledore 0.125000 0.000000 0.125000 ( 0.103964)
基准报告以秒为单位的执行时间。结果被发现是非常一致的。
请注意,在我执行的所有测试中,数组的列数至少与行数一样大。这是因为每当行数超过列数时,Humbledore的代码中就会引发NoMethodError (undefined method '[]=' for nil:NilClass)
异常。 (例如,尝试test 3,2,1
。)错误消息出现在以下代码块的第二行。
(layer...cols - 1 - layer).each do |i|
result[rows - 1 - layer][i] = row[idx]
idx += 1
idx %= row.size
end
我希望这个问题很容易解决。