Ruby 在二维数组中查找邻接项

Ruby 在二维数组中查找邻接项,ruby,Ruby,我有一个这样的2d数组 [ ["+", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-&

我有一个这样的2d数组

[
  ["+", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "+"], 
  ["|", "*", "*", " ", " ", "*", " ", " ", " ", " ", "*", "*", "*", "*", "*", "*", "*", "*", " ", "*", " ", "|"], 
  ["|", " ", "*", "*", "*", "*", " ", " ", " ", " ", "*", "*", " ", " ", "*", "*", " ", "*", " ", "*", " ", "|"], 
  ["|", "*", " ", "*", " ", " ", " ", " ", "*", " ", "*", " ", "*", "*", "*", " ", "*", "*", "*", " ", "*", "|"], 
  ["|", "*", "*", " ", " ", "*", " ", " ", "*", "*", "*", " ", "*", " ", "*", "*", " ", "*", "*", " ", " ", "|"], 
  ["|", "*", " ", " ", " ", "*", " ", "*", " ", " ", " ", "*", "*", "*", "*", "*", " ", " ", " ", "*", "*", "|"], 
  ["|", " ", " ", " ", " ", " ", "*", " ", "*", " ", " ", " ", "*", " ", " ", " ", " ", " ", "*", " ", " ", "|"], 
  ["|", "*", "*", " ", "*", "*", "*", " ", "*", " ", " ", "*", "*", "*", "*", " ", "*", " ", " ", "*", " ", "|"], 
  ["|", " ", "*", " ", "*", "*", "*", "*", " ", " ", " ", "*", "*", " ", " ", " ", " ", "*", " ", "*", "*", "|"], 
  ["|", " ", "*", " ", " ", "*", " ", " ", "*", " ", "*", "*", "*", " ", "*", " ", "*", " ", " ", " ", "*", "|"], 
  ["|", " ", "*", "*", "*", "*", " ", " ", " ", " ", "*", "*", " ", "*", "*", "*", " ", " ", " ", "*", "*", "|"], 
  ["|", " ", " ", "*", "*", " ", "*", "*", "*", " ", " ", " ", " ", " ", " ", "*", "*", " ", " ", " ", " ", "|"], 
  ["|", "*", " ", "*", "*", " ", "*", " ", "*", "*", " ", " ", " ", "*", " ", "*", "*", "*", " ", " ", " ", "|"], 
  ["|", " ", " ", " ", "*", " ", "*", " ", "*", " ", "*", " ", " ", " ", " ", " ", " ", "*", "*", " ", " ", "|"], 
  ["|", "*", " ", "*", " ", "*", " ", "*", " ", " ", " ", "*", " ", "*", "*", " ", "*", "*", "*", "*", "*", "|"], 
  ["|", " ", " ", " ", "*", " ", "*", "*", "*", "*", "*", "*", " ", " ", "*", " ", " ", "*", "*", " ", "*", "|"], 
  ["|", "*", "*", "*", "*", "*", " ", " ", " ", "*", " ", "*", " ", "*", "*", " ", "*", "*", " ", " ", "*", "|"], 
  ["|", "*", " ", " ", " ", "*", "*", "*", "*", " ", " ", "*", " ", "*", " ", "*", " ", "*", " ", "*", "*", "|"], 
  ["|", "*", " ", "*", "*", "*", "*", "*", "*", " ", "*", "*", "*", "*", " ", " ", " ", "*", " ", " ", " ", "|"], 
  ["|", " ", " ", "*", " ", " ", "*", "*", " ", " ", " ", "*", " ", "*", "*", " ", " ", " ", " ", " ", "*", "|"], 
  ["|", " ", "*", " ", " ", " ", "*", "*", "*", "*", "*", "*", "*", "*", "*", "*", "*", " ", " ", " ", "*", "|"], 
  ["+", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "+"]
]
我需要找到每个“*”附近的炸弹数量,如下图所示

我这样做是为了得到索引,但我不知道如何得到邻接

@array_map.each_index do |i|
subarray = @array_map[i]
 subarray.each_index do |x|
    puts String(i) << " " << String(x) << "... " << @array_map[i][x]
 end
end
@array_map.each_index do|i|
子阵列=@array_map[i]
子数组。每个|u索引do | x|
字符串(i)
显示

["+", "-", "-", "-", "-", "-", "-", "-"]
["|", "*", "*", "4", "4", "*", "2", "0"]
["|", "4", "*", "*", "*", "*", "2", "0"]
["|", "*", "6", "*", "5", "3", "2", "0"]
["|", "*", "*", "2", "3", "*", "3", "1"]
["|", "*", "3", "1", "2", "*", "4", "*"]
["|", "1", "1", "0", "1", "2", "*", "2"]
adj_cols
是一个散列,它给出一个列索引数组,以标识每个列索引的相邻位置。在开始时这样做一次是有意义的,而不是对
雷区的每个元素(行)重复计算

要返回的数组已初始化为

minefield.dup.map(&:dup)  
这样,
雷区
就不会发生变异(修改)

下面是一个计算示例

i = 3
adj_rows = ([i-1, 0].max..[i+1, last_row].min).to_a
  #=> ([2, 0].max..[4, 6].min).to_a
  #=> (2..4).to_a
  #=> [2, 3, 4]   
j = 4
a = adj_cols[j]
  #=> [3, 4, 5]
b = adj_rows.product(a)
  #=> [[2, 3], [2, 4], [2, 5],
  #    [3, 3], [3, 4], [3, 5],
  #    [4, 3], [4, 4], [4, 5]] 
b.count { |r,c| minefield[r][c] == '*' }
  #=> 5
注意
b
包括
[3,4]
,我们知道这等于
'
。但是,将其保留在
计数
操作中并没有坏处,因为
雷区[r][c]='*'#=>假
)。我们也可以这样写:

b = adj_rows.product(a) - [[i, j]]
  #=> [[2, 3], [2, 4], [2, 5],
  #    [3, 3],         [3, 5],
  #    [4, 3], [4, 4], [4, 5]] 
下面是第二个示例(如果
雷区[0][4]#=>”
,则适用)

对于问题中给出的
雷区
数组,返回值如下所示

["+", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "+"]
["|", "*", "*", "4", "4", "*", "2", "0", "0", "2", "*", "*", "*", "*", "*", "*", "*", "*", "4", "*", "2", "|"]
["|", "4", "*", "*", "*", "*", "2", "1", "1", "4", "*", "*", "6", "7", "*", "*", "7", "*", "6", "*", "3", "|"]
["|", "*", "6", "*", "5", "3", "2", "2", "*", "6", "*", "6", "*", "*", "*", "6", "*", "*", "*", "4", "*", "|"]
["|", "*", "*", "2", "3", "*", "3", "3", "*", "*", "*", "6", "*", "8", "*", "*", "5", "*", "*", "5", "3", "|"]
["|", "*", "3", "1", "2", "*", "4", "*", "4", "4", "3", "*", "*", "*", "*", "*", "3", "3", "4", "*", "*", "|"]
["|", "3", "3", "2", "3", "5", "*", "5", "*", "2", "2", "5", "*", "7", "5", "4", "2", "2", "*", "4", "3", "|"]
["|", "*", "*", "4", "*", "*", "*", "6", "*", "2", "2", "*", "*", "*", "*", "2", "*", "3", "4", "*", "3", "|"]
["|", "4", "*", "5", "*", "*", "*", "*", "3", "3", "4", "*", "*", "6", "3", "4", "3", "*", "3", "*", "*", "|"]
["|", "3", "*", "6", "6", "*", "5", "3", "*", "3", "*", "*", "*", "5", "*", "4", "*", "2", "3", "5", "*", "|"]
["|", "2", "*", "*", "*", "*", "4", "4", "3", "4", "*", "*", "4", "*", "*", "*", "4", "2", "1", "*", "*", "|"]
["|", "2", "5", "*", "*", "6", "*", "*", "*", "4", "3", "2", "3", "3", "6", "*", "*", "3", "2", "2", "2", "|"]
["|", "*", "3", "*", "*", "6", "*", "7", "*", "*", "2", "1", "1", "*", "3", "*", "*", "*", "3", "1", "0", "|"]
["|", "2", "4", "4", "*", "5", "*", "5", "*", "4", "*", "2", "3", "3", "4", "4", "6", "*", "*", "4", "2", "|"]
["|", "*", "2", "*", "4", "*", "5", "*", "5", "5", "5", "*", "3", "*", "*", "3", "*", "*", "*", "*", "*", "|"]
["|", "3", "5", "5", "*", "5", "*", "*", "*", "*", "*", "*", "5", "5", "*", "5", "5", "*", "*", "6", "*", "|"]
["|", "*", "*", "*", "*", "*", "6", "6", "6", "*", "6", "*", "5", "*", "*", "4", "*", "*", "5", "5", "*", "|"]
["|", "*", "6", "5", "7", "*", "*", "*", "*", "4", "5", "*", "7", "*", "5", "*", "5", "*", "4", "*", "*", "|"]
["|", "*", "4", "*", "*", "*", "*", "*", "*", "3", "*", "*", "*", "*", "5", "2", "3", "*", "3", "3", "3", "|"]
["|", "2", "4", "*", "4", "5", "*", "*", "6", "5", "6", "*", "8", "*", "*", "4", "3", "2", "1", "2", "*", "|"]
["|", "1", "*", "2", "1", "2", "*", "*", "*", "*", "*", "*", "*", "*", "*", "*", "*", "1", "0", "2", "*", "|"]
["+", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "+"]
这将有助于:

minefield = [
  ["+", "-", "-", "-", "-", "-", "+"],
  ["|", "*", "*", "*", "*", "*", "|"],
  ["|", "*", " ", "*", "*", " ", "|"],
  ["|", " ", " ", " ", "*", " ", "|"],
  ["|", "*", " ", "*", "*", "*", "|"],
  ["|", "*", "*", "*", " ", " ", "|"],
  ["+", "-", "-", "-", "-", "-", "+"]
]

minefield.each_with_index do |row, y|
  row.each_with_index do |item, x|
    next unless item == '*'

    (y - 1).upto(y + 1) do |j|
      (x - 1).upto(x + 1) do |i|
        next if minefield[j][i] =~ /[*|+-]/

        minefield[j][i] = minefield[j][i].to_i.succ.to_s
      end
    end
  end
end
它穿过雷场阵列,跳过除炸弹以外的所有东西(
next,除非item='*'
)。一旦我们遇到炸弹,我们就会穿越它的周围,跳过任何特殊的字段,如
*
|
+
,或
-
。(这也将跳过炸弹本身)

由于炸弹不会发生在雷区边界,我们可以忽略边界检查

对于其余的周围字段(即空格和数字字符串),我们将该字段转换为整数(因此
变为
0
),添加1(通过
succ
),将其转换回字符串并重新分配给字段:(
succ
也适用于字符串,但无论如何我们必须处理

最后,空白字段已被炸弹计数取代:

[
  ["+", "-", "-", "-", "-", "-", "+"],
  ["|", "*", "*", "*", "*", "*", "|"],
  ["|", "*", "5", "*", "*", "4", "|"],
  ["|", "2", "4", "5", "*", "4", "|"],
  ["|", "*", "5", "*", "*", "*", "|"],
  ["|", "*", "*", "*", "4", "2", "|"],
  ["+", "-", "-", "-", "-", "-", "+"]
]

你怎么知道边境上没有炸弹?我在童年时错过了什么吗?
b = adj_rows.product(a) - [[i, j]]
  #=> [[2, 3], [2, 4], [2, 5],
  #    [3, 3],         [3, 5],
  #    [4, 3], [4, 4], [4, 5]] 
i = 0
j = 4
adj_rows = ([i-1, 0].max..[i+1, last_row].min).to_a
  #=> [0, 1]   
j = 4
a = adj_cols[j]
  #=> [3, 4, 5]
b = adj_rows.product(a)
  #=> [[0, 3], [0, 4], [0, 5],
  #    [1, 3], [1, 4], [1, 5]] 
["+", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "+"]
["|", "*", "*", "4", "4", "*", "2", "0", "0", "2", "*", "*", "*", "*", "*", "*", "*", "*", "4", "*", "2", "|"]
["|", "4", "*", "*", "*", "*", "2", "1", "1", "4", "*", "*", "6", "7", "*", "*", "7", "*", "6", "*", "3", "|"]
["|", "*", "6", "*", "5", "3", "2", "2", "*", "6", "*", "6", "*", "*", "*", "6", "*", "*", "*", "4", "*", "|"]
["|", "*", "*", "2", "3", "*", "3", "3", "*", "*", "*", "6", "*", "8", "*", "*", "5", "*", "*", "5", "3", "|"]
["|", "*", "3", "1", "2", "*", "4", "*", "4", "4", "3", "*", "*", "*", "*", "*", "3", "3", "4", "*", "*", "|"]
["|", "3", "3", "2", "3", "5", "*", "5", "*", "2", "2", "5", "*", "7", "5", "4", "2", "2", "*", "4", "3", "|"]
["|", "*", "*", "4", "*", "*", "*", "6", "*", "2", "2", "*", "*", "*", "*", "2", "*", "3", "4", "*", "3", "|"]
["|", "4", "*", "5", "*", "*", "*", "*", "3", "3", "4", "*", "*", "6", "3", "4", "3", "*", "3", "*", "*", "|"]
["|", "3", "*", "6", "6", "*", "5", "3", "*", "3", "*", "*", "*", "5", "*", "4", "*", "2", "3", "5", "*", "|"]
["|", "2", "*", "*", "*", "*", "4", "4", "3", "4", "*", "*", "4", "*", "*", "*", "4", "2", "1", "*", "*", "|"]
["|", "2", "5", "*", "*", "6", "*", "*", "*", "4", "3", "2", "3", "3", "6", "*", "*", "3", "2", "2", "2", "|"]
["|", "*", "3", "*", "*", "6", "*", "7", "*", "*", "2", "1", "1", "*", "3", "*", "*", "*", "3", "1", "0", "|"]
["|", "2", "4", "4", "*", "5", "*", "5", "*", "4", "*", "2", "3", "3", "4", "4", "6", "*", "*", "4", "2", "|"]
["|", "*", "2", "*", "4", "*", "5", "*", "5", "5", "5", "*", "3", "*", "*", "3", "*", "*", "*", "*", "*", "|"]
["|", "3", "5", "5", "*", "5", "*", "*", "*", "*", "*", "*", "5", "5", "*", "5", "5", "*", "*", "6", "*", "|"]
["|", "*", "*", "*", "*", "*", "6", "6", "6", "*", "6", "*", "5", "*", "*", "4", "*", "*", "5", "5", "*", "|"]
["|", "*", "6", "5", "7", "*", "*", "*", "*", "4", "5", "*", "7", "*", "5", "*", "5", "*", "4", "*", "*", "|"]
["|", "*", "4", "*", "*", "*", "*", "*", "*", "3", "*", "*", "*", "*", "5", "2", "3", "*", "3", "3", "3", "|"]
["|", "2", "4", "*", "4", "5", "*", "*", "6", "5", "6", "*", "8", "*", "*", "4", "3", "2", "1", "2", "*", "|"]
["|", "1", "*", "2", "1", "2", "*", "*", "*", "*", "*", "*", "*", "*", "*", "*", "*", "1", "0", "2", "*", "|"]
["+", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "+"]
minefield = [
  ["+", "-", "-", "-", "-", "-", "+"],
  ["|", "*", "*", "*", "*", "*", "|"],
  ["|", "*", " ", "*", "*", " ", "|"],
  ["|", " ", " ", " ", "*", " ", "|"],
  ["|", "*", " ", "*", "*", "*", "|"],
  ["|", "*", "*", "*", " ", " ", "|"],
  ["+", "-", "-", "-", "-", "-", "+"]
]

minefield.each_with_index do |row, y|
  row.each_with_index do |item, x|
    next unless item == '*'

    (y - 1).upto(y + 1) do |j|
      (x - 1).upto(x + 1) do |i|
        next if minefield[j][i] =~ /[*|+-]/

        minefield[j][i] = minefield[j][i].to_i.succ.to_s
      end
    end
  end
end
                   #  blank  # numeric
minefield[j][i]    #=> " "   #   "1"
  .to_i            #=> 0     #   1
  .succ            #=> 1     #   2
  .to_s            #=> "1"   #   "2"
[
  ["+", "-", "-", "-", "-", "-", "+"],
  ["|", "*", "*", "*", "*", "*", "|"],
  ["|", "*", "5", "*", "*", "4", "|"],
  ["|", "2", "4", "5", "*", "4", "|"],
  ["|", "*", "5", "*", "*", "*", "|"],
  ["|", "*", "*", "*", "4", "2", "|"],
  ["+", "-", "-", "-", "-", "-", "+"]
]