我有一个9x9多维数组,表示一个数独游戏。我需要把它分成9×3的多个部分。怎么做?我完全不知道从哪里开始,在这里。
game = [
[1, 3, 2, 5, 7, 9, 4, 6, 8],
[4, 9, 8, 2, 6, 1, 3, 7, 5],
[7, 5, 6, 3, 8, 4, 2, 1, 9],
[6, 4, 3, 1, 5, 8, 7, 9, 2],
[5, 2, 1, 7, 9, 3, 8, 4, 6],
[9, 8, 7, 4, 2, 6, 5, 3, 1],
[2, 1, 4, 9, 3, 5, 6, 8, 7],
[3, 6, 5, 8, 1, 7, 9, 2, 4],
[8, 7, 9, 6, 4, 2, 1, 5, 3]
]
分成块,就变成
chunk_1 = [
[1, 3, 2],
[4, 9, 8],
[7, 5, 6]
]
chunk_2 = [
[5, 7, 9],
[2, 6, 1],
[3, 8, 4]
]
...and so on
最佳答案
那是个有趣的练习!
回答
game.each_slice(3).map{|stripe| stripe.transpose.each_slice(3).map{|chunk| chunk.transpose}}.flatten(1)
这将很麻烦,不需要定义每个
chunk_1, chunk_2, ...
。如果您想要
chunk_2
,可以使用extract_chunks(game)[1]
它输出
[chunk_1, chunk_2, chunk_3, ..., chunk_9]
,所以它是一个数组数组:1 3 2
4 9 8
7 5 6
5 7 9
2 6 1
3 8 4
4 6 8
3 7 5
2 1 9
6 4 3
5 2 1
...
您可以定义一个方法来检查此网格是否有效(它是):
def extract_chunks(game)
game.each_slice(3).map{|stripe| stripe.transpose.each_slice(3).map{|chunk| chunk.transpose}}.flatten(1)
end
class Array # NOTE: Use refinements if you don't want to patch Array
def has_nine_unique_elements?
self.flatten(1).uniq.size == 9
end
end
def valid?(game)
game.has_nine_unique_elements? &&
game.all?{|row| row.has_nine_unique_elements? } &&
game.all?{|column| column.has_nine_unique_elements? } &&
extract_chunks(game).all?{|chunk| chunk.has_nine_unique_elements? }
end
puts valid?(game) #=> true
理论
大网格可以sliced成3条条纹,每个条纹包含3行9个单元格。
第一个条带将包含chunk_1、chunk_2和chunk_3。
我们需要把带子垂直切成三大块。为此:
我们在脱衣舞上,
用transpose水平切割,
又回来了。
我们对条纹2和3做
each_slice
。为了避免返回一组由多行单元格组成的条带,我们使用transpose删除一个级别并返回一组由多行单元格组成的条带:)