[英]Python: How to make my 4-coloring checker more readable
I was trying to write a general program to check The 17x17 problem SOLVED! 我试图编写一个通用程序来检查17x17问题已解决! , 4-coloring of a17x17 grid with no monochromatic rectangles.
,a17x17网格的4色,没有单色矩形。 Solution link: 17.txt .
解决方案链接: 17.txt 。
This is what I wrote: 这就是我写的:
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)
Is there a more readable, concise or efficient way (in that order of priority) to write this? 是否有更可读,简洁或有效的方式(按照优先顺序)来写这个? Maybe a different approach with different data structures... Since i am learning Python at the moment, any advice is very welcome.
也许是采用不同数据结构的不同方法......由于我目前正在学习Python,所以非常欢迎任何建议。
import
ed by another file). import
)。 My attempt (taking the file from STDIN, can be called like python script.py < 17.txt
): 我的尝试(从STDIN获取文件,可以像
python script.py < 17.txt
一样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)
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)
Assuming you've loaded the 17x17 data into a numpy
array
named A
(see @robertking's answer to use urllib), you can do it with one line with numpy! 假设您已将17x17数据加载到名为
A
的numpy
array
(请参阅@ robertking的使用urllib的答案),您可以使用numpy的一行来完成!
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()
* Don't actually do this in one-line. *实际上不要在一行中这样做。 Here it is expanded out a bit for clarity:
为了清楚起见,它稍微扩展了一下:
corners = zip(*[(0,0), (0,-1),(-1,0),(-1,-1)])
for k1 in xrange(2,17):
for k2 in xrange(2,17):
for i in xrange(16):
for j in xrange(16):
# Pull out each sub-rectange
sub = A[i:i+k1, j:j+k2]
# Only use the corners
sub = sub[corners]
# Count the number of unique elements
uniq = len(set(sub))
# Check if all corners are the same
if uniq == 1:
print False
exit()
print True
Here is another way to think about it. 这是考虑它的另一种方式。
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)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.