Arrays 如何将9x9阵列拆分为9个3x3组件
我有一个9x9多维数组,代表一个数独游戏。我需要把它分解成9个3x3的多个组件。如何做到这一点?我完全不知道从这里开始Arrays 如何将9x9阵列拆分为9个3x3组件,arrays,ruby,Arrays,Ruby,我有一个9x9多维数组,代表一个数独游戏。我需要把它分解成9个3x3的多个组件。如何做到这一点?我完全不知道从这里开始 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,
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
那是一个有趣的练习 答复 这会很麻烦,不需要定义每个
块1、块2、
如果您想要chunk\u 2
,可以使用extract\u chunk(游戏)[1]
它输出[chunk\u 1,chunk\u 2,chunk\u 3,…,chunk\u 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
...
您可以定义一个方法来检查此网格是否有效(它是):
学说
- 大网格可以有3条条纹,每条条纹包含3行9个单元格
- 第一个条带将包含块_1、块_2和块_3
- 我们需要把这条带子垂直切成3块。为此:
- 我们在脱衣舞
- 用刀横切
- 再来一次
- 我们为条纹2和条纹3做测试
- 为了避免返回单元格行块的条纹数组,我们使用删除一个级别并返回单元格行块数组。:)李>
块1、块2、
如果您想要chunk\u 2
,可以使用extract\u chunk(游戏)[1]
它输出[chunk\u 1,chunk\u 2,chunk\u 3,…,chunk\u 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
...
您可以定义一个方法来检查此网格是否有效(它是):
学说
- 大网格可以有3条条纹,每条条纹包含3行9个单元格
- 第一个条带将包含块_1、块_2和块_3
- 我们需要把这条带子垂直切成3块。为此:
- 我们在脱衣舞
- 用刀横切
- 再来一次
- 我们为条纹2和条纹3做测试
- 为了避免返回单元格行块的条纹数组,我们使用删除一个级别并返回单元格行块数组。:)李>
require 'matrix'
def sub3x3(game, i, j)
Matrix[*game].minor(3*i, 3, 3*j, 3).to_a
end
chunk1 = sub3x3(game, 0, 0)
#=> [[1, 3, 2], [4, 9, 8], [7, 5, 6]]
chunk2 = sub3x3(game, 0, 1)
#=> [[5, 7, 9], [2, 6, 1], [3, 8, 4]]
chunk3 = sub3x3(game, 0, 2)
#=> [[4, 6, 8], [3, 7, 5], [2, 1, 9]]
chunk4 = sub3x3(game, 1, 0)
#=> [[6, 4, 3], [5, 2, 1], [9, 8, 7]]
...
chunk9 = sub3x3(game, 2, 2)
#=> [[6, 8, 7], [9, 2, 4], [1, 5, 3]]
Ruby没有数组的“行”和“列”的概念。因此,为了方便起见,我将在偏移量I
和j
(I=0,1,2
,j=0,1,2
)处引用game
的3x3“子数组”,作为m=Matrix[*game]
的3x3子矩阵,其左上角值位于3*I
的行偏移量和m
的列偏移量3*j
,转换为数组
这是相对低效的,因为为每个“块”的计算创建了一个新的矩阵。考虑到阵列的大小,这不是一个问题,但与其提高效率,不如重新考虑总体设计。创建九个局部变量(而不是,比方说,一个由九个数组组成的数组)不是一条可行之路
这里有一个建议,用于在填充完所有打开的单元格后检查game
(使用上述方法sub3x3
)的有效性。请注意,我使用了,其中唯一有效的条目是数字1-9,并且我假设当玩家在单元格中输入值时,代码强制执行该要求
def invalid_vector_index(game)
game.index { |vector| vector.uniq.size < 9 }
end
def sub3x3_invalid?(game, i, j)
sub3x3(game, i, j).flatten.uniq.size < 9
end
def valid?(game)
i = invalid_vector_index(game)
return [:ROW_ERR, i] if i
j = invalid_vector_index(game.transpose)
return [:COL_ERR, j] if j
m = Matrix[*game]
(0..2).each do |i|
(0..2).each do |j|
return [:SUB_ERR, i, j] if sub3x3_invalid?(game, i, j)
end
end
true
end
valid?(game)
#=> true
所以
行和列显然仍然有效,但此返回值表示至少有一个3x3子数组无效,并且数组无效
[[6, 4, 3],
[5, 2, 1],
[2, 1, 4]]
第一个被发现是无效的。该方法是为此量身定做的:
require 'matrix'
def sub3x3(game, i, j)
Matrix[*game].minor(3*i, 3, 3*j, 3).to_a
end
chunk1 = sub3x3(game, 0, 0)
#=> [[1, 3, 2], [4, 9, 8], [7, 5, 6]]
chunk2 = sub3x3(game, 0, 1)
#=> [[5, 7, 9], [2, 6, 1], [3, 8, 4]]
chunk3 = sub3x3(game, 0, 2)
#=> [[4, 6, 8], [3, 7, 5], [2, 1, 9]]
chunk4 = sub3x3(game, 1, 0)
#=> [[6, 4, 3], [5, 2, 1], [9, 8, 7]]
...
chunk9 = sub3x3(game, 2, 2)
#=> [[6, 8, 7], [9, 2, 4], [1, 5, 3]]
Ruby没有数组的“行”和“列”的概念。因此,为了方便起见,我将在偏移量I
和j
(I=0,1,2
,j=0,1,2
)处引用game
的3x3“子数组”,作为m=Matrix[*game]
的3x3子矩阵,其左上角值位于3*I
的行偏移量和m
的列偏移量3*j
,转换为数组
这是相对低效的,因为为每个“块”的计算创建了一个新的矩阵。考虑到阵列的大小,这不是一个问题,但与其提高效率,不如重新考虑总体设计。创建九个局部变量(而不是,比方说,一个由九个数组组成的数组)不是一条可行之路
这里有一个建议,用于在填充完所有打开的单元格后检查game
(使用上述方法sub3x3
)的有效性。请注意,我使用了,其中唯一有效的条目是数字1-9,并且我假设当玩家在单元格中输入值时,代码强制执行该要求
def invalid_vector_index(game)
game.index { |vector| vector.uniq.size < 9 }
end
def sub3x3_invalid?(game, i, j)
sub3x3(game, i, j).flatten.uniq.size < 9
end
def valid?(game)
i = invalid_vector_index(game)
return [:ROW_ERR, i] if i
j = invalid_vector_index(game.transpose)
return [:COL_ERR, j] if j
m = Matrix[*game]
(0..2).each do |i|
(0..2).each do |j|
return [:SUB_ERR, i, j] if sub3x3_invalid?(game, i, j)
end
end
true
end
valid?(game)
#=> true
所以
行和列显然仍然有效,但此返回值表示至少有一个3x3子数组无效,并且数组无效
[[6, 4, 3],
[5, 2, 1],
[2, 1, 4]]
第一个被发现无效。您可以创建一个从给定索引生成单个3X3块的方法。由于数独板的长度为9,因此将为您生成9 3X3块。见下文
#steps
#you'll loop through each index of the board
#to get the x value
#you divide the index by 3 and multiply by 3
#to get the y value
#you divide the index by 3, take remainder and multiply by 3
#for each x value, you can get 3 y values
#this will give you a single 3X3 box from one index so
def three_by3(index, sudoku)
#to get x value
x=(index/3)*3
#to get y value
y=(index%3)*3
(x...x+3).each_with_object([]) do |x,arr|
(y...y+3).each do |y|
arr<<sudoku[x][y]
end
end
end
sudoku = [ [1,2,3,4,5,6,7,8,9],
[2,3,4,5,6,7,8,9,1],
[3,4,5,6,7,8,9,1,2],
[1,2,3,4,5,6,7,8,9],
[2,3,4,5,6,7,8,9,1],
[3,4,5,6,7,8,9,1,2],
[1,2,3,4,5,6,7,8,9],
[2,3,4,5,6,7,8,9,1],
[3,4,5,6,7,8,9,1,2]]
p (0...sudoku.length).map {|i| three_by3(i,sudoku)}
#output:
#[[1, 2, 3, 2, 3, 4, 3, 4, 5],
# [4, 5, 6, 5, 6, 7, 6, 7, 8],
# [7, 8, 9, 8, 9, 1, 9, 1, 2],
# [1, 2, 3, 2, 3, 4, 3, 4, 5],
# [4, 5, 6, 5, 6, 7, 6, 7, 8],
# [7, 8, 9, 8, 9, 1, 9, 1, 2],
# [1, 2, 3, 2, 3, 4, 3, 4, 5],
# [4, 5, 6, 5, 6, 7, 6, 7, 8],
# [7, 8, 9, 8, 9, 1, 9, 1, 2]]
#步骤
#您将循环浏览董事会的每个索引
#获取x值的步骤
#将索引除以3,再乘以3
#获取y值
#将索引除以3,取余数并乘以3
#对于每个x值,可以得到3个y值
#这将从一个索引中获得一个3X3框,因此
定义三乘三(索引,数独)
#得到x值
x=(指数/3)*3
#得到y值
y=(索引%3)*3
(x…x+3)。每个带有对象([])的对象都做x,arr|
(y…y+3)。每个都是|
arr您可以创建一个从给定索引生成单个3X3块的方法。由于数独板的长度为9,因此将为您生成9 3X3块。见下文
#steps
#you'll loop through each index of the board
#to get the x value
#you divide the index by 3 and multiply by 3
#to get the y value
#you divide the index by 3, take remainder and multiply by 3
#for each x value, you can get 3 y values
#this will give you a single 3X3 box from one index so
def three_by3(index, sudoku)
#to get x value
x=(index/3)*3
#to get y value
y=(index%3)*3
(x...x+3).each_with_object([]) do |x,arr|
(y...y+3).each do |y|
arr<<sudoku[x][y]
end
end
end
sudoku = [ [1,2,3,4,5,6,7,8,9],
[2,3,4,5,6,7,8,9,1],
[3,4,5,6,7,8,9,1,2],
[1,2,3,4,5,6,7,8,9],
[2,3,4,5,6,7,8,9,1],
[3,4,5,6,7,8,9,1,2],
[1,2,3,4,5,6,7,8,9],
[2,3,4,5,6,7,8,9,1],
[3,4,5,6,7,8,9,1,2]]
p (0...sudoku.length).map {|i| three_by3(i,sudoku)}
#output:
#[[1, 2, 3, 2, 3, 4, 3, 4, 5],
# [4, 5, 6, 5, 6, 7, 6, 7, 8],
# [7, 8, 9, 8, 9, 1, 9, 1, 2],
# [1, 2, 3, 2, 3, 4, 3, 4, 5],
# [4, 5, 6, 5, 6, 7, 6, 7, 8],
# [7, 8, 9, 8, 9, 1, 9, 1, 2],
# [1, 2, 3, 2, 3, 4, 3, 4, 5],
# [4, 5, 6, 5, 6, 7, 6, 7, 8],
# [7, 8, 9, 8, 9, 1, 9, 1, 2]]
#步骤
#您将循环浏览董事会的每个索引
#获取x值的步骤
#将索引除以3,再乘以3
#获取y值
#将索引除以3,取余数并乘以3
#对于每个x值,可以得到3个y值
#这将从一个索引中获得一个3X3框,因此
def th