给定N×N网格,其中网格中的所有位置都标记为“是”,“否”或“”(空格)。
在网格中查找包含5个连续“”(空格)的所有可能序列。这里“连续空间”可以是垂直的,水平的或对角线的。
我们可以假设网格表示为字典,其中字典的每个键表示一个位置作为坐标,每个值表示位置上是否有“是”,“否”或“” 。
例如,grid [(1,2)] =“Yes”。表示网格上的位置(1,2)处有“是”。
我们还可以假设N的值是事先知道的。
我对此问题的初步处理包括从头开始循环遍历整个网格,检查水平序列,然后检查垂直序列,然后检查对角线序列。然而,这将被证明是低效的,因为我必须每次不断地重新计算序列的长度,确保它们等于5以及检查序列是否是连续的。
我一直在寻找一种更优雅的方法,这是一种更好的方法。是否有允许进行此类计算的Python库?我试过看但没找到任何符合问题限制的东西。
任何指导都将不胜感激!
答案 0 :(得分:1)
使用scipy
;明确地,使用scipy.ndimage.label
函数,它将连接的序列标记在一起。
import scipy, scipy.ndimage
# N and grid dictionary are already known
G = scipy.zeros([N,N])
for k, v in grid.iteritems():
if v.lower() == 'yes':
G[tuple(k)] = 1
elif v.lower() == 'no':
G[tuple(k)] = -1
def get_consecutive_spaces(G, chain=5):
sequences = []
# Generate a pattern for each directional sequence. (1) Horizontal,
# (2) vertical, (3) top-left to bottom-right diagonal, (4) bottom-left
# to top-right diagonal
patterns = [scipy.ndimage.label(G == 0, structure = scipy.array([[0,0,0],
[1,1,1],
[0,0,0]])),
scipy.ndimage.label(G == 0, structure = scipy.array([[0,1,0],
[0,1,0],
[0,1,0]])),
scipy.ndimage.label(G == 0, structure = scipy.array([[1,0,0],
[0,1,0],
[0,0,1]])),
scipy.ndimage.label(G == 0, structure = scipy.array([[0,0,1],
[0,1,0],
[1,0,0]]))]
# Loop over patterns, then find any labelled sequence >= a size of chain=5
for lab_arr, n in patterns:
for i in range(1, n+1):
b = lab_arr == i
b_inds = scipy.where(b)
if len(b_inds[0]) < chain:
continue
sequences.append((tuple(b_inds[0]), tuple(b_inds[1])))
return sequences
E.g。
>>> G = scipy.sign(scipy.random.random([12,12]) - 0.5)*(scipy.random.random([12,12]) < 0.5)
>>> print G
[[-0. 1. -1. 1. 1. -1. 1. 0. -0. 1. 0. -0.]
[ 1. 1. -0. -0. -1. 1. 1. -1. -1. 1. -0. -1.]
[ 0. 1. 1. 1. 0. 1. -0. 0. 0. 0. -0. 0.]
[ 1. -0. -1. 0. -1. -0. 1. 0. -0. -0. -0. 1.]
[-0. 1. -1. 1. -0. -0. -1. -0. 1. 1. -0. 0.]
[ 0. -1. 1. -0. 1. 0. -0. -1. -1. -0. 0. -1.]
[-1. -0. 0. -1. -1. -0. -1. 0. 0. 0. -1. 0.]
[-0. 1. 0. 0. 0. 1. 1. -1. 0. -0. -1. 0.]
[ 1. 1. 0. 1. -1. -1. 0. 0. -1. 1. 0. 0.]
[-0. 0. 0. -1. -0. -1. 1. -0. 0. 1. 1. 0.]
[-1. 1. -1. 1. 0. 1. 0. 1. 1. 1. 1. 0.]
[-1. 1. -0. 0. -1. 0. -0. -1. 1. -1. -0. 0.]]
>>> sequences = get_consecutive_spaces(G)
>>> for s in sequences: print s
((2, 2, 2, 2, 2, 2), (6, 7, 8, 9, 10, 11))
((0, 1, 2, 3, 4, 5), (10, 10, 10, 10, 10, 10))
((6, 7, 8, 9, 10, 11), (11, 11, 11, 11, 11, 11))
((0, 1, 2, 3, 4, 5, 6, 7), (11, 10, 9, 8, 7, 6, 5, 4))
((2, 3, 4, 5, 6), (6, 5, 4, 3, 2))
((4, 5, 6, 7, 8), (11, 10, 9, 8, 7))
注意,返回大于或等于链的序列;并不限制自己只有5个长度的序列。将其更改为只有5的长度是一个微不足道的修复。