我在两个数组中有多个填字游戏线索,用于上下线索(每个线索都是一对 - [clue_number,clue_length]。我正在尝试为这个填字游戏找到一个兼容的网格,(假设所有的答案单词都是相同的字母,即不要打扰实际的答案 - 只需使用长度和数字来找到兼容的网格。
我假设网格是13 x 13(这个测试示例,我知道,有一个13 x 13的解决方案)。到目前为止,我正在计算所有组合,用于在黑色方块中定位“跨”字。我们的想法是检查每个选项,如果它也适合下行线索,接受它。然而,这已经有~10 ^ 17种组合(网格尺寸为13 x 13和上述测试数据集)。我想知道是否有更有效的方法在合理的时间内解决这个问题。我到目前为止的代码如下所示:
ACROSS_CLUES = [
[1, 5], [6, 5], [9, 7], [10, 5], [11, 5], [12, 5], [13, 7], [15, 3], [17, 4],[18, 6],[19, 5], [20, 6], [22, 4], [24, 3], [25, 7], [26, 5], [27, 5], [28, 5], [29, 7], [30, 5], [31, 5]]
DOWN_CLUES = [
[2, 6], [3, 6], [4, 3], [5, 5], [6, 7], [7, 4], [8, 6], [12, 5], [13, 5], [14, 5], [15, 5], [16, 5], [18, 5], [19, 7], [21, 6], [22, 6], [23, 6], [25, 5], [26, 4], [28, 3]
]
ACROSS_DIRECTION = :across
DOWN_DIRECTION = :down
# merge the across and down clues into a single array sorted by the clue number
CLUES = ACROSS_CLUES.map{|ac|ac + [:across]} + DOWN_CLUES.map{|dc| dc + [:down]}.sort_by{|c| c.first}
UNINITIALIZED = -2
BLACK = -1
BLANK = 0
SIDE = 13
SIZE = SIDE ** 2
# a fragment is a string of clue_length characters (number followed by blanks), which is rendered in the grid
def get_fragment(clue)
clue_number = clue[0]
clue_length = clue[1]
fragment = [clue_number] + Array.new(clue_length - 1, BLANK)
end
# returns the first compatible grid found
def get_grid
fragments = []
ACROSS_CLUES.each do |clue|
fragments << get_fragment(clue)
end
across_clues_length = fragments.flatten.count
grid = Array.new(SIZE - across_clues_length + fragments.length, UNINITIALIZED)
grid_length = grid.length
(0..(grid_length - 1)).to_a.combination(fragments.length).each do |num_locations|
fragments.each_with_index do |fragment, fragment_index|
num_location = num_locations[fragment_index]
grid[num_location] = fragment
end
grid.flatten!
# TODO: check if grid is compatible, return if valid; reject if invalid
grid = Array.new(SIZE - across_clues_length + fragments.length, UNINITIALIZED)
end
grid
end
grid = get_grid