2015-09-26 51 views
-3

主要问题:您可以轻松地从阵列中获取子阵列,例如sub = a [2,3]。但是如果你有一个2D数组,你怎么能得到一个2D子数组?二维子阵列(一个较大的正方形中的较小正方形)

实际示例: 我试图遍历数独板中的9个3x3正方形,以检查每个3x3正方形的重复数字。

如果我有9个阵列(行)的数组(板),有没有简单的方法来获得板的3x3子2D阵列?是否有一种简单的方法可以通过所有9个3x3子2D阵列?

编辑:对不起,如果原件不清楚,主要是获取二维数组的一部分的原则,数独部分更多的是原则的应用。

+0

你真的需要澄清你的问题(与编辑)二者兼而有之(并且可能会扭转)下降趋势,并为将来阅读它的SO成员带来利益。您需要清楚准确地陈述您的问题,这些问题现在是隐含的和模糊的(因此是降价)。我假定问题是,“给定由数组'solution'表示的Sudoku解决方案,使得'solution [i] [j]'是行'i + 1'中的条目(整数或字符串),列'j + 1'(行'1'到'9',列'1'到'9'),我如何确定9个3x3块中是否有任何一个包含重复条目? –

+0

是的,@ Mirror318是否试图验证谜题已解决或只是试图展示一个难题来解决? – Charles

+1

你好!你好!有人在家吗? –

回答

0

我不明白你为什么有行,这会让它变得复杂。

我建议您只需要一个长度为81的数组a。给定索引i,您可以假定它所属的行,列或子平方的起始元素,其索引被指定为:

start_of_row  = (i/9) * 9 
start_of_column  = i % 9 
start_of_sub_square = (i/27) * 27 + (i % 9/3) * 3 

然后,给定一个起始索引j,您可以通过行,列迭代,子方如下:

row_indice  = [0, 1, 2, 3, 4, 5, 6, 7, 8] 
column_indice  = [0, 9, 18, 27, 36, 45, 54, 63, 72] 
sub_square_indice = [0, 1, 2, 9, 10, 11, 18, 19, 20] 
  • 迭代行:row_indice.each{|k| a[j + k]}
  • 迭代列:column_indice.each{|k| a[j + k]}
  • 迭代子方:sub_square_indice.each{|k| a[j + k]}
2

你可以判断一个数独的解决方案是有效的,如下所示。使用方法Array#minor可以简化检查3x3块的过程。

代码

require 'matrix' 

def valid?(soln) 
    rows_invalid = invalid_rows?(soln, "rows") 
    cols_invalid = invalid_rows?(soln.transpose, "columns") 
    blocks_invalid = invalid_blocks?(soln) 
    puts "Solution is valid" unless rows_invalid || cols_invalid || blocks_invalid 
end 

def invalid_rows?(soln, label) 
    rows_with_dups = soln.each.with_index(1).select { |r,i| r.uniq.size < r.size } 
    return false if rows_with_dups.empty? 
    puts "Duplicates are in #{label}: #{ rows_with_dups.map(&:last).join(' ') }" 
    return true 
end 

def invalid_blocks?(soln) 
    m = Matrix[*soln] 
    blocks_with_dups = [1,2,3].product([1,2,3]).select do |row,col| 
    f_row, f_col = 3*(row-1), 3*(col-1) 
    block = m.minor(f_row..(f_row+2), f_col..(f_col+2)).to_a.flatten 
    block.uniq.size < block.size 
    end 
    return false if blocks_with_dups.empty? 
    puts "Duplicates are in blocks: #{ blocks_with_dups.map { |row,col| 
    "(#{row}, #{col})" }.join(' ') }" 
    return true 
end 

例子

soln = [ 
    %w| 4 1 7 8 5 3 9 6 2 |, 
    %w| 5 8 9 7 6 2 4 3 1 |, 
    %w| 6 3 2 9 1 4 7 5 8 |, 
    %w| 9 6 8 3 2 1 5 7 4 |, 
    %w| 7 2 3 4 8 5 1 9 6 |, 
    %w| 1 5 4 6 7 9 8 2 3 |, 
    %w| 8 4 6 2 9 7 3 1 5 |, 
    %w| 2 7 1 5 3 8 6 4 9 |, 
    %w| 3 9 5 1 4 6 2 8 7 |, 
] 
    #=> [["4", "1", "7", "8", "5", "3", "9", "6", "2"], 
    # ["5", "8", "9", "7", "6", "2", "4", "3", "1"], 
    # ["6", "3", "2", "9", "1", "4", "7", "5", "8"], 
    # ["9", "6", "8", "3", "2", "1", "5", "7", "4"], 
    # ["7", "2", "3", "4", "8", "5", "1", "9", "6"], 
    # ["1", "5", "4", "6", "7", "9", "8", "2", "3"], 
    # ["8", "4", "6", "2", "9", "7", "3", "1", "5"], 
    # ["2", "7", "1", "5", "3", "8", "6", "4", "9"], 
    # ["3", "9", "5", "1", "4", "6", "2", "8", "7"]] 

valid?(soln) 
    #=> "Solution is valid" 

现在改变两个元素在soln

soln[0][5] = "7" 
soln[8][8] = "3" 
soln.map { |row| row.join(' ') } 
    #=> ["4 1 7 8 5 7 9 6 2", 
    # "5 8 9 7 6 2 4 3 1", 
    # "6 3 2 9 1 4 7 5 8", 
    # "9 6 8 3 2 1 5 7 4", 
    # "7 2 3 4 8 5 1 9 6", 
    # "1 5 4 6 7 9 8 2 3", 
    # "8 4 6 2 9 7 3 1 5", 
    # "2 7 1 5 3 8 6 4 9", 
    # "3 9 5 1 4 6 2 8 3"] 

valid?(soln) 
    #=> Duplicates are in rows: 1 9 
    # Duplicates are in columns: 6 9 
    # Duplicates are in blocks: (1, 2) (3, 3) 
相关问题