Ruby中的矩阵环旋转

Ruby中的矩阵环旋转,ruby,algorithm,matrix,graph,Ruby,Algorithm,Matrix,Graph,这是一个黑客等级问题(),需要旋转一个矩阵R次。 矩阵是MxN 我提出的解决方案会旋转每个环(外部->内部)。然而,这是相当低效的,它没有通过测试 #!/usr/bin/ruby def print_matrix(matrix) matrix.each do |a| a.each do |n| print "#{n} " end puts end puts end def rotate_ring(

这是一个黑客等级问题(),需要旋转一个矩阵R次。 矩阵是MxN

我提出的解决方案会旋转每个环(外部->内部)。然而,这是相当低效的,它没有通过测试

#!/usr/bin/ruby
def print_matrix(matrix)
    matrix.each do |a|
        a.each do |n|
            print "#{n} "
        end
        puts 
    end
    puts
end

def rotate_ring(matrix,s_i,s_j,m,n)
    rotated = matrix.inject([]) { |a,element| a << element.dup }
    for i in (s_i...m)
        for j in (s_j...n)
            case [i,j]
                # Move items on corners
                #Top Left Corner
                when [s_i,s_j]
                    rotated[i+1][j] = matrix[i][j]
                #Bottom Left Corner
                when [m-1,s_j]
                    rotated[i][j+1] = matrix[i][j]
                #Bottom Right Corner
                when [m-1,n-1]
                    rotated[i-1][j] = matrix[i][j]
                #Top Right Corner
                when [s_i,n-1]
                    rotated[i][j-1] = matrix[i][j]
                ##################  
                # Move other items
                # Top Row
                when proc{|i,j| i == s_i and j>0 }
                    rotated[i][j-1] = matrix[i][j]
                # Bottom Row
                when proc{|i,j| i == m-1}
                    rotated[i][j+1] = matrix[i][j]
                # Left Column
                when proc{|i,j| i >= 0 and j == s_j}
                    rotated[i+1][j] = matrix[i][j]
                # Right Column
                when proc{|i,j| i >= 0 and j == n-1}
                rotated[i-1][j] = matrix[i][j]
            end
        end
    end
    return rotated
end

def rotate_matrix(matrix,m,n,r)
    s_i = 0
    s_j = 0
    min = ([m,n].min)/2
    r.times do
        for t in 0...min
            matrix = rotate_ring(matrix,0+t,0+t,m-t,n-t)
        end
    end
    return matrix
end

matrix = [['a','b','c','d'],
          ['e','f','g','h'],
          ['i','j','k','l'],
          ['m','n','o','p'],    
          ['q','r','s','t']]

m = matrix.size
n = matrix[0].size

print_matrix(matrix)
print_matrix(rotate_matrix(matrix,m,n,1))
#/usr/bin/ruby
def打印矩阵(矩阵)
矩阵。每个do | a|
a、 每个都有|
打印“#{n}”
结束
放
结束
放
结束
def旋转环(矩阵、s_i、s_j、m、n)
旋转=矩阵。注入([]){| a,元素| a 0}
旋转[i][j-1]=矩阵[i][j]
#底层
当proc{i,j{i==m-1}
旋转[i][j+1]=矩阵[i][j]
#左列
当proc{i,j{i>=0且j==s|j}
旋转[i+1][j]=矩阵[i][j]
#右栏
当proc{i,j{i>=0且j==n-1}
旋转[i-1][j]=矩阵[i][j]
结束
结束
结束
旋转返回
结束
def旋转矩阵(矩阵,m,n,r)
s_i=0
s_j=0
最小值=([m,n].min)/2
r、 时代确实如此
对于0…分钟内的t
矩阵=旋转环(矩阵,0+t,0+t,m-t,n-t)
结束
结束
返回矩阵
结束
矩阵=[[a','b','c','d'],
[e'、'f'、'g'、'h'],
[i',j',k',l'],
[m',n',o',p'],
[q'、'r'、's'、't']
m=矩阵大小
n=矩阵[0]。大小
打印矩阵(矩阵)
打印矩阵(旋转矩阵(矩阵,m,n,1))
代码

def rotate_rings(arr, n)
  m = arr.transpose.transpose
  n.times { rotate_rings_once(m) }
  m
end

def rotate_rings_once(arr)
  nrings = (arr.size/2)
  m = arr.transpose.transpose
  4.times do
    nrings.times { |i| arr[i][i..-i-1] = m[i][i+1..-i-1] << m[i+1][-i-1] }
    rotate_array!(arr)
    rotate_array!(m)
  end
end

def rotate_array!(arr)
  arr.replace(arr.map!(&:reverse).transpose)
end

注意事项:

  • 旋转数组
    是一种辅助方法,它原地逆时针旋转其参数(数组)。例如:

    m = [[10, 11, 12, 13],
         [14, 15, 16, 17],
         [18, 19, 20, 21],
         [22, 23, 24, 25],
         [26, 27, 28, 20]] 
    
    rotate_array!(m)
      #=> [[13, 17, 21, 25, 20],
      #    [12, 16, 20, 24, 28],
      #    [11, 15, 19, 23, 27],
      #    [10, 14, 18, 22, 26]]` 
    
  • rotate\u数组的返回值
    也是其参数
    m
    的新值。如果我们旋转
    4次
    ,我们将返回原始数组

  • 目的是:

    m = arr.transpose.transpose
    
  • 是制作arr的深度副本,这样后者就不会发生变异。我也可以使用:

        m = arr.dup.map(:&dup)
    
  • 中,旋转环一次(arr)

  • 是数组中的环数。环
    i
    i=0,1,…,nrings-1)
    )的左上角元素是
    arr[i][i]
    。对于每个环
    i
    ,使用以下表达式计算环的顶行:

        arr[i][i..-i-1] = m[i][i+1..-i-1] << m[i+1][-i-1]
    

    arr[i][i..-i-1]=m[i][i+1..-i-1]谢谢@Cary我真的很感谢你花时间回答。我试着按照你的解决办法,但似乎没有给出正确的答案。图:显示矩阵应如何旋转。我的代码很有效,只是效率很低,我希望能得到一些改进的建议。等我有时间再看一看。
    
        m = arr.dup.map(:&dup)
    
    nrings = (arr.size/2)
    
        arr[i][i..-i-1] = m[i][i+1..-i-1] << m[i+1][-i-1]