我试图编写一个通用程序来检查The 17x17 problem SOLVED!,没有单色矩形的a17x17网格的4色。解决方案链接:17.txt。
这就是我写的:
from itertools import product
def is_solution(myfile,m,n):
""" m-lines, n-columns """
grid = [c.strip() for c in line.split(',')] for line in open(myfile).readlines()]
for x0,y0 in product(xrange(m),xrange(n)):
start = grid[x0][y0]
for x in xrange(x0+1,m):
if grid[x][y0] == start:
for y in xrange(y0+1,n):
if grid[x0][y] == start == grid[x][y]:
return False
return True
print is_solution('17.txt',17,17)
是否有更可读,简洁或有效的方式(按照优先顺序)来写这个?也许是采用不同数据结构的不同方法......因为我现在正在学习Python,所以非常欢迎任何建议。
答案 0 :(得分:4)
import
由另一个文件调用的文件)。我的尝试(从STDIN获取文件,可以像python script.py < 17.txt
一样调用):
import itertools
def has_monochromatic_rectangles(grid):
# use range instead of xrange here (xrange is not in Python 3)
points = list(itertools.product(range(len(grid)), range(len(grid[0]))))
# check if for any rectangle, all 4 colors are equal
# (this is more brute-force than necessary, but you placed simplicity
# above efficiency. Also, for 17x17, it doesn't matter at all ;)
return any(grid[x1][y1] == grid[x1][y2] == grid[x2][y1] == grid[x2][y2]
for (x1,y1), (x2,y2) in itertools.product(points, points)
if x1 != x2 and y1 != y2)
def has_max_colors(grid, most):
# collect all grid values and uniquify them by creating a set
return len(set(sum(grid, []))) <= most
if __name__ == '__main__':
# read from STDIN (could easily be adapted to read from file, URL, ...)
import sys
grid = [map(int, line.split(',')) for line in sys.stdin]
assert has_max_colors(grid, 4)
assert not has_monochromatic_rectangles(grid)
答案 1 :(得分:1)
import urllib
grid=urllib.urlopen("http://www.cs.umd.edu/~gasarch/BLOGPAPERS/17.txt")
grid=[map(int,row.split(",")) for row in grid]
print grid
def check_grid(grid):
for i in range(17):
for j in range(17):
for i2 in range(i):
for j2 in range(j):
colours=[grid[a][b] for a in (i,i2) for b in (j,j2)]
assert(len(set(colours))>1)
check_grid(grid)
grid[1][1]=2
check_grid(grid)
答案 2 :(得分:1)
假设您已将17x17数据加载到名为numpy
的{{1}} array
中(请参阅@ robertking的使用urllib的答案),您可以使用numpy的一行执行此操作!< / p>
A
*实际上不要在一行中这样做。为了清楚起见,它在这里进行了扩展:
print (array([len(set(A[i:i+k1,j:j+k2][zip(*[(0,0), (0,-1),(-1,0),(-1,-1)])])) for i in xrange(16) for j in xrange(16) for k1 in xrange(2,17) for k2 in xrange(2,17)])!=1).all()
答案 3 :(得分:0)
这是考虑它的另一种方式。
import urllib
grid=urllib.urlopen("http://www.cs.umd.edu/~gasarch/BLOGPAPERS/17.txt")
grid=[map(int,row.split(",")) for row in grid]
def check(grid):
colour_positions=lambda c,row:set(i for i,colour in enumerate(row) if colour==c) #given a row and a colour, where in the row does that colour occur
to_check=[[colour_positions(c,row) for row in grid] for c in range(1,5)] #for each row and each colour, get the horizontal positions.
from itertools import combinations
for i in to_check:
for a,b in combinations(i,2):
if len(a&b)>1: #for each colour, for each combination of rows, do we ever get more than 1 horizontal position in common (e.g. a rectangle)
return False
return True
print check(grid)
grid[1][1]=2
print check(grid)