我想最简单的解释方法是使用tictactoe的类比。 tictactoe板可以表示为二进制状态的二维数组。
所以电路板#可以显示为[[1,2,3],[1,2,3],[1,2,3]] 并且此数组的每个索引都具有二进制值(X或O) 因此,要检查一个极化器是否赢了,你可以检查一个获胜模式中的所有3个方格是否共享相同的状态。
现在,在这个类比中,您可以对获胜的解决方案进行硬编码并独立地对其进行检查,但在我的情况下,我不想硬编码它们,因为我需要(最终)生成数组并且运行时的模式。所以目前我只能手动检查或硬编码,但我需要找到一种方法来检查这些模式而无需硬编码解决方案。
这是我目前提供示例的最小数组:
[[[1,a], [2,a], [3,a]],
[[3,a], [1,a], [2,a]],
[[1,a], [2,a], [3,a]]]
现在' a'是空白状态,将被替换为' b'或者' c' (或任何两个名称)和1,2和& 3指定' line'。
了解'行'相互交叉? 那么这个数组中的模式是:
在较大的阵列中有更多的模式,但是我能做的最简单。
任何人都可以帮我找出解决方案来找到生成的模式,以便检查他们的状态吗? 我在python中测试这个,但我也可以使用纯粹的数学解决方案
答案 0 :(得分:1)
一种方法是逐行扫描网格,并为每个位置跟踪所有可能方向上的图案长度轨迹。在这种情况下,方向将是左上角 - >右下方,右上方 - >左下,左 - >正确的沿着'线。当处理每个位置时,如果状态将其他设置值与0匹配,则将先前模式的值递增1。每当找到目标长度或网格已完全迭代时停止。
以上是一个简短的例子,其中单元格具有二元状态:
grid = [
[[1, 0], [2, 0], [3, 1]],
[[3, 1], [1, 0], [2, 0]],
[[1, 0], [2, 0], [3, 1]]
]
def find(g, length):
# Top left -> bottom right, top right -> bottom left
# and left -> right lengths are stored here
prev = [[0] * 3 for _ in xrange(len(g[0]))]
# 'Line' length is stored here for efficiency
prev_line = {}
for row in grid:
cur = []
cur_line = {}
for i in xrange(len(row)):
tl = line = tr = left = 0
if row[i][1] == 1:
# Up left
tl = 1 + (prev[i-1][0] if i else 0)
# Line
line = 1 + prev_line.get(row[i][0], 0)
# Up right
tr = 1 + (prev[i+1][1] if i < len(row) - 1 else 0)
# Straight Left
left = 1 + (cur[i-1][2] if i else 0)
if any(x == length for x in (tl, line, tr, left)):
return True
cur.append([tl, tr, left])
cur_line[row[i][0]] = line
prev = cur
prev_line = cur_line
return False
find(grid, 3) # True