我有一个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删除一个级别并返回一组由多行单元格组成的条带:)

09-19 20:27