Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Arrays 如何将9x9阵列拆分为9个3x3组件_Arrays_Ruby - Fatal编程技术网

Arrays 如何将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,

我有一个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, 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