''' We have a box width 2 and height 4+1/3 Goal is to find a convex body in there with cooridinates being multiples of 1/3 that does not contain any integer point inside. Rewrite of the original problem to integers by multiplying everyting by 3. Goal: Find K with vertices at integer coordinates that does not contain any vertex whose both coordinate are divisible by 3. Moreover, for every integer vector c: max - min >= 6. We also know the width of K is EXACTLY 6 and the height is at most 13. ''' # Size of the grid, the +1 is there for the for cycle bounts Gx = 7 Gy = 14 def printm(m): print(m.transpose()[::-1,:]) print() # Here for given points of a polygone, test if any # of the int_points is inside (or on the boundary) # def polygon_contains(vertices, points_to_test): p = Polyhedron(vertices=vertices) for one_point in points_to_test: if p.contains(one_point): return True return False def can_add_point(m, int_points, picked_points, x, y): # Do not pick integer points as vertices.... if m[x,y] != 1: return False # Adding a point already inside is bad if polygon_contains(picked_points, [[x,y]]) == True: return False # Adding a point that results in integer polytope is bad if polygon_contains(picked_points+[[x,y]], int_points) == True: return False # Adding a point that makes a previously picked point obsolete is bad for i in range(len(picked_points)): if polygon_contains(picked_points[:i]+picked_points[i+1:]+[[x,y]], [picked_points[i]]) == True: return False return True # This is the main recursive procedure # def try_adding_points(foundcounter, m, int_points, picked_points, id_x_to_pick, picking_order): if polygon_contains(picked_points, int_points) == True: print("Something is wrong", picked_points, id_x_to_pick, picking_order) return #if id_x_to_pick == 1: # print (picked_points, "Found so far=", foundcounter[0]) if id_x_to_pick >= len(picking_order): foundcounter[0] += 1 # Check if min/max in y-coordinate is at least 6 for c in [[0,1],[1,1],[-1,-1],[1, -1],[-2,1],[2,1],[3,2],[3,-2]]: if max([c[0]*x+c[1]*y for [x,y] in picked_points]) - min([c[0]*x+c[1]*y for [x,y] in picked_points]) < 6: print ("pp=",picked_points," c=",c) return print("ERROR! No c is working for", picked_points) return x_to_pick = picking_order[id_x_to_pick] #print(picked_points, x_to_pick) # Pick upper and lower point for yx in range(Gy): if can_add_point(m, int_points, picked_points, x_to_pick,yx): # Try to pick a second point above for yxb in range(yx+1,Gy): if can_add_point(m, int_points, picked_points+[[x_to_pick,yx]],x_to_pick,yxb): try_adding_points(foundcounter, m, int_points, picked_points+[[x_to_pick,yx],[x_to_pick,yxb]], id_x_to_pick +1, picking_order) # or don't pick a second one try_adding_points(foundcounter, m, int_points, picked_points+[[x_to_pick,yx]], id_x_to_pick+1, picking_order) # Pick nothing at all for the middle ones if id_x_to_pick >= 2: try_adding_points(foundcounter, m, int_points, picked_points, id_x_to_pick +1, picking_order) # -1 denotes points with integer coordinates, they need to be avoided for sx in [0,1,2]: grid=[[1]*Gy for x in range(Gx)] m=matrix(grid) foundcounter = [0] # List of pairs of points picked_points=[] # List of points with integer coordinates int_points = [] # Initialize the points with integer coordinates for x in range(int(Gx/3)+1): if (3*x+sx < Gx): for y in range(int(Gy/3)+1): m[3*x+sx,3*y] = -1 int_points.append([3*x+sx,3*y]) print("Testing new shift sx=",sx,"-1 denotes a forbidden coordiante") printm(m) print("Forbidden coordinates:", int_points) print("Generated polygons:") try_adding_points(foundcounter, m, int_points, picked_points, 0, [0,6,3,1,2,4,5]) print("Shift sx=",sx,"generated", foundcounter[0],"candidates") print ("Done")