2016-04-24 15 views
0

我正在写一个脚本,它需要两个参数,一个二维数组(全0和1)以及最大垂直距离n,并返回一个修改后的数组。使得如果n = 3以下数组红宝石阵列金字塔形修改

[[0,0,0,0,0,0,0], 
[0,0,0,0,0,0,0], 
[0,0,0,0,0,0,0], 
[0,0,0,1,0,0,0], 
[0,0,0,0,0,0,0], 
[0,0,0,0,0,0,0], 
[0,0,0,0,0,0,0]] 

返回

[[0,0,0,1,0,0,0], 
[0,0,1,1,1,0,0], 
[0,1,1,1,1,1,0], 
[1,1,1,1,1,1,1], 
[0,1,1,1,1,1,0], 
[0,0,1,1,1,0,0], 
[0,0,0,1,0,0,0]] 

(数组输入可以具有任何尺寸的矩形;任何元件可以是10)。

我的想法是克隆原始数组,将其扫描为1,并将更改映射到克隆中。我想先右侧,然后映射改变原来的1

左边我得到了以下的工作,这改变了阵列的中心柱:

a = [[0,0,0,0,0,0,0], 
    [0,0,0,0,0,0,0], 
    [0,0,0,0,0,0,0], 
    [0,0,0,1,0,0,0], 
    [0,0,0,0,0,0,0], 
    [0,0,0,0,0,0,0], 
    [0,0,0,0,0,0,0]] 

cloned = a.map(&:clone) 

n = 3 

a.each.with_index do |whole_row, row| 
    whole_row.each.with_index do |cell, column| 
     if cell == 1 

      #center column 
      row_path = row - n 
      (n*2+1).times do 
       unless (cloned[row_path][column]).nil? 
        cloned[row_path][column] = 1 
       end 
       row_path += 1 
      end 

     end 
    end 
end 

cloned 

但是,当我尝试将此过程迭代到右侧时,我得到了undefined method '[]' for nil:NilClass。我在哪里搞乱这里的逻辑?

a = [[0,0,0,0,0,0,0], 
    [0,0,0,0,0,0,0], 
    [0,0,0,0,0,0,0], 
    [0,0,0,1,0,0,0], 
    [0,0,0,0,0,0,0], 
    [0,0,0,0,0,0,0], 
    [0,0,0,0,0,0,0]] 

cloned = a.map(&:clone) 

n = 3 

a.each.with_index do |whole_row, row| 
    whole_row.each.with_index do |cell, column| 
     if cell == 1 

      #central column & right side 
      row_path = row - n 
      column_path = column 
      repetition = 2 * n + 1 
      (n+1).times do 
       (repetition).times do 
        unless cloned[row_path][column_path].nil? 
         cloned[row_path][column_path] = 1 
        end 
        row_path += 1 
       end 
       repetition -= 2 
       column_path += 1 
       row_path += 1 
      end 
     end 
    end 
end 

cloned 

(我的想法是执行此程序两次,在原始数组的右侧,然后左侧)。

+0

您需要在单词中定义“最大垂直距离”(通过编辑您的问题)。这个例子是不够的。另外,你的意思是什么元素可以是10? –

回答

1

从你例如我已经假定在[i,j][k,l]元件之间的“垂直距离”是通过该方法给定:

def dist((i,j),(k,l)) 
    (i-k).abs + (j-l).abs 
end 

在这种情况下,“矩形距离”将是更好的描述符。如果这个假设是不正确的,你不需要再读。

对于示例:

a = [[0,0,0,0,0,0,0], 
    [0,0,0,0,0,0,0], 
    [0,0,0,0,0,0,0], 
    [0,0,0,1,0,0,0], 
    [0,0,0,0,0,0,0], 
    [0,0,0,0,0,0,0], 
    [0,0,0,0,0,0,0]] 

n = 3 

限定上述方法dist之后,可以构建所需的阵列如下:

nrows = a.size 
    #=> 7 
ncols = a.first.size 
    #=> 7 

Array.new(nrows) do |i| 
    Array.new(ncols) do |j| 
    nrows.times.any? do |k| 
     ncols.times.any? do |l| 
     a[k][l] == 1 && dist([i,j],[k,l]) <= n 
     end 
    end ? 1 : 0 
    end 
end 
    #=> [[0, 0, 0, 1, 0, 0, 0], 
    # [0, 0, 1, 1, 1, 0, 0], 
    # [0, 1, 1, 1, 1, 1, 0], 
    # [1, 1, 1, 1, 1, 1, 1], 
    # [0, 1, 1, 1, 1, 1, 0], 
    # [0, 0, 1, 1, 1, 0, 0], 
    # [0, 0, 0, 1, 0, 0, 0]] 

或者,可以围绕做它的其他方式(与nrowsncols计算)。

b = Array.new(nrows) { Array.new(ncols,0) } 
nrows.times.each do |i| 
    ncols.times.each do |j| 
    next unless a[i][j]==1 
    nrows.times.each do |k| 
     ncols.times.each do |l| 
     b[k][l] = 1 if dist([i,j],[k,l]) <= n 
     end 
    end 
    end 
end     
b 

这两种方法都可以通过限制检查的行(作为目标行和n的函数)进行更高效的,并且对于每个行认为,通过限制检查的列(作为的函数行,目标行和列和n)。

1

发生此错误的原因是您尝试访问不存在的数组索引的子数组中的项目。

此行 - cloned[row_path][column_path].nil?这里的row_path在某些迭代中不具有任何价值,那是因为您正在增加它两次。

(repetition).times中删除增量应该可以修复它。

希望这有助于

0

考虑Dwijen的回答,我调整了脚本,以便有索引里面没有零测试时。我得到的误差,直到我说继续unless (row_path > cloned.length - 1)这通过测试:

a.each.with_index do |whole_row, row| 
    whole_row.each.with_index do |cell, column| 
    if cell == 1 

     #central column & right side 
     row_path = row - n 
     column_path = column 
     repetition = 2 * n + 1 
     counter = 0 
     (n+1).times do 
     (repetition).times do 
      unless (row_path > cloned.length - 1) || cloned[row_path][column_path].nil? 
      cloned[row_path][column_path] = 1 
      end 
      row_path += 1 
     end 
     counter += 1 
     repetition -= 2 
     column_path += 1 
     row_path = row - n + counter 
     end 

     #central column & left side 
     row_path = row - n 
     column_path = column 
     repetition = 2 * n + 1 
     counter = 0 
     (n+1).times do 
     (repetition).times do 
      unless (row_path > cloned.length - 1) || cloned[row_path][column_path].nil? 
      cloned[row_path][column_path] = 1 
      end 
      row_path += 1 
     end 
     counter -= 1 
     repetition -= 2 
     column_path -= 1 
     row_path = row - n - counter 
     end 

    end 
    end 
end