def test_int_payloads(self): lattice = get_square_lattice(3) sym = make_number_range_symbol_set(1, 9) sg = SymbolGrid(lattice, sym) sc = ShapeConstrainer(lattice, [ Shape([ (Vector(0, 0), 1), (Vector(0, 1), 2), (Vector(1, 0), 4), ]), Shape([ (Vector(0, 1), 3), (Vector(1, 0), 5), (Vector(1, 1), 6), (Vector(2, 1), 9), ]), Shape([ (Vector(0, 0), 7), (Vector(0, 1), 8), ]), ], solver=sg.solver, complete=True) for p in lattice.points: sg.solver.add(sg.cell_is(p, sc.shape_payload_grid[p])) self.assertTrue(sg.solve()) solved_grid = sg.solved_grid() for p in lattice.points: self.assertEqual(solved_grid[p], lattice.point_to_index(p) + 1) self.assertTrue(sg.is_unique())
def main(): """SLICY solver example.""" sym = grilops.SymbolSet(["S", "L", "I", "C", "Y", ("W", " ")]) lattice = PointyToppedHexagonalLattice([ areas_row_col_to_point(r, c) for r in range(len(AREAS)) for c in range(len(AREAS[r])) ]) sg = grilops.SymbolGrid(lattice, sym) rc = grilops.regions.RegionConstrainer(lattice, solver=sg.solver, complete=True) sc = ShapeConstrainer( lattice, [ # Note that the example shapes are shown as flat-topped hexagons, so # you need to turn the page sideways to see them as pointy-topped ones. Shape([Vector(0, 0), Vector(1, 1), Vector(1, 3), Vector(2, 4)]), # S Shape([Vector(0, 0), Vector(0, 2), Vector(0, 4), Vector(-1, 5)]), # L Shape([Vector(0, 0), Vector(0, 2), Vector(0, 4), Vector(0, 6)]), # I Shape([Vector(0, 0), Vector(1, 1), Vector(1, 3), Vector(0, 4)]), # C Shape([Vector(0, 0), Vector(2, 0), Vector(1, 1), Vector(1, 3)]), # Y ], solver=sg.solver, allow_rotations=True, allow_reflections=True, allow_copies=True) link_symbols_to_shapes(sym, sg, sc) add_area_constraints(lattice, sc) add_sea_constraints(sym, sg, rc) add_adjacent_tetrahex_constraints(lattice, sc) if sg.solve(): sg.print() print() if sg.is_unique(): print("Unique solution") else: print("Alternate solution") sg.print() print() else: print("No solution")
def main(): """Shape solver example.""" points = [] for y, row in enumerate(GRID): for x, c in enumerate(row): if c == "O": points.append(Point(y, x)) lattice = RectangularLattice(points) shapes = [ Shape([Vector(0, 0), Vector(1, 0), Vector(2, 0), Vector(3, 0)]), # I Shape([Vector(0, 0), Vector(1, 0), Vector(2, 0), Vector(2, 1)]), # L Shape([Vector(0, 1), Vector(0, 2), Vector(1, 0), Vector(1, 1)]), # S ] sym = grilops.SymbolSet([("B", chr(0x2588) * 2), ("W", " ")]) sg = grilops.SymbolGrid(lattice, sym) sc = ShapeConstrainer(lattice, shapes, sg.solver, complete=False, allow_rotations=True, allow_reflections=True, allow_copies=False) for p in points: sg.solver.add(sg.cell_is(p, sym.W) == (sc.shape_type_grid[p] == -1)) for n in sg.vertex_sharing_neighbors(p): np = n.location sg.solver.add( Implies( And(sc.shape_type_grid[p] != -1, sc.shape_type_grid[np] != -1), sc.shape_type_grid[p] == sc.shape_type_grid[np])) if sg.solve(): sg.print() print() sc.print_shape_types() print() if sg.is_unique(): print("Unique solution") else: print("Alternate solution") sg.print() else: print("No solution")
def main(): """LITS solver example.""" sym = grilops.SymbolSet(["L", "I", "T", "S", ("W", " ")]) lattice = grilops.get_rectangle_lattice(HEIGHT, WIDTH) sg = grilops.SymbolGrid(lattice, sym) rc = grilops.regions.RegionConstrainer(lattice, solver=sg.solver) sc = ShapeConstrainer( lattice, [ Shape([Vector(0, 0), Vector(1, 0), Vector(2, 0), Vector(2, 1)]), # L Shape([Vector(0, 0), Vector(1, 0), Vector(2, 0), Vector(3, 0)]), # I Shape([Vector(0, 0), Vector(0, 1), Vector(0, 2), Vector(1, 1)]), # T Shape([Vector(0, 0), Vector(1, 0), Vector(1, 1), Vector(2, 1)]), # S ], solver=sg.solver, allow_rotations=True, allow_reflections=True, allow_copies=True) link_symbols_to_shapes(sym, sg, sc) add_area_constraints(lattice, sc) add_nurikabe_constraints(sym, sg, rc) add_adjacent_tetronimo_constraints(lattice, sc) if sg.solve(): sg.print() print() sc.print_shape_types() print() sc.print_shape_instances() print() if sg.is_unique(): print("Unique solution") else: print("Alternate solution") sg.print() print() sc.print_shape_types() print() sc.print_shape_instances() print() else: print("No solution")
def main(): """Status Park (Loop) solver example.""" for row in GIVENS: for cell in row: sys.stdout.write(cell) print() points = [] for y, row in enumerate(GIVENS): for x, c in enumerate(row): if c != X: points.append(Point(y, x)) lattice = RectangularLattice(points) sym = grilops.loops.LoopSymbolSet(lattice) sym.append("EMPTY", " ") sg = grilops.SymbolGrid(lattice, sym) grilops.loops.LoopConstrainer(sg, single_loop=True) sc = ShapeConstrainer( lattice, [Shape([Vector(y, x) for y, x in shape]) for shape in SHAPES], solver=sg.solver, allow_rotations=True, allow_reflections=True, allow_copies=False) for p in points: if GIVENS[p.y][p.x] == W: # White circles must be part of the loop. sg.solver.add(sym.is_loop(sg.grid[p])) elif GIVENS[p.y][p.x] == B: # Black circles must be part of a shape. sg.solver.add(sc.shape_type_grid[p] != -1) # A cell is part of the loop if and only if it is not part of # any shape. sg.solver.add(sym.is_loop(sg.grid[p]) == (sc.shape_type_grid[p] == -1)) # Orthogonally-adjacent cells must be part of the same shape. for n in sg.edge_sharing_neighbors(p): np = n.location sg.solver.add( Implies( And(sc.shape_type_grid[p] != -1, sc.shape_type_grid[np] != -1), sc.shape_type_grid[p] == sc.shape_type_grid[np])) if sg.solve(): sg.print() print() sc.print_shape_types() print() if sg.is_unique(): print("Unique solution") else: print("Alternate solution") sg.print() else: print("No solution")
def test_datatype_payloads(self): lattice = get_square_lattice(3) sym = make_number_range_symbol_set(0, 2) row_grid = SymbolGrid(lattice, sym) col_grid = SymbolGrid(lattice, sym, solver=row_grid.solver) RowCol = Datatype("RowCol") RowCol.declare("row_col", ("row", IntSort()), ("col", IntSort())) RowCol = RowCol.create() sc = ShapeConstrainer(lattice, [ Shape([ (Vector(0, 0), RowCol.row_col(0, 0)), (Vector(0, 1), RowCol.row_col(0, 1)), (Vector(1, 0), RowCol.row_col(1, 0)), ]), Shape([ (Vector(0, 1), RowCol.row_col(0, 2)), (Vector(1, 0), RowCol.row_col(1, 1)), (Vector(1, 1), RowCol.row_col(1, 2)), (Vector(2, 1), RowCol.row_col(2, 2)), ]), Shape([ (Vector(0, 0), RowCol.row_col(2, 0)), (Vector(0, 1), RowCol.row_col(2, 1)), ]), ], solver=row_grid.solver, complete=True) for p in lattice.points: row_grid.solver.add( row_grid.cell_is(p, RowCol.row(sc.shape_payload_grid[p]))) col_grid.solver.add( col_grid.cell_is(p, RowCol.col(sc.shape_payload_grid[p]))) self.assertTrue(row_grid.solve()) solved_row_grid = row_grid.solved_grid() solved_col_grid = col_grid.solved_grid() for p in lattice.points: self.assertEqual(solved_row_grid[p], p.y) self.assertEqual(solved_col_grid[p], p.x) self.assertTrue(row_grid.is_unique())
def test_no_payloads(self): lattice = get_square_lattice(3) sym = make_number_range_symbol_set(0, 2) sg = SymbolGrid(lattice, sym) sc = ShapeConstrainer(lattice, [ Shape([ Vector(0, 0), Vector(0, 1), Vector(1, 0), ]), Shape([ Vector(0, 1), Vector(1, 0), Vector(1, 1), Vector(2, 1), ]), Shape([ Vector(0, 0), Vector(0, 1), ]), ], solver=sg.solver, complete=True) for p in lattice.points: sg.solver.add(sg.cell_is(p, sc.shape_type_grid[p])) self.assertTrue(sg.solve()) solved_grid = sg.solved_grid() expected = [ [0, 0, 1], [0, 1, 1], [2, 2, 1], ] for p in lattice.points: self.assertEqual(solved_grid[p], expected[p.y][p.x]) self.assertTrue(sg.is_unique())
def main(): """Battleship solver example.""" sg = grilops.SymbolGrid(LATTICE, SYM) sc = ShapeConstrainer(LATTICE, [ Shape([Vector(0, i) for i in range(4)]), Shape([Vector(0, i) for i in range(3)]), Shape([Vector(0, i) for i in range(3)]), Shape([Vector(0, i) for i in range(2)]), Shape([Vector(0, i) for i in range(2)]), Shape([Vector(0, i) for i in range(2)]), Shape([Vector(0, i) for i in range(1)]), Shape([Vector(0, i) for i in range(1)]), Shape([Vector(0, i) for i in range(1)]), ], solver=sg.solver, allow_rotations=True) # Constrain the given ship segment counts and ship segments. for y, count in enumerate(GIVENS_Y): sg.solver.add( PbEq([(Not(sg.cell_is(Point(y, x), SYM.X)), 1) for x in range(WIDTH)], count)) for x, count in enumerate(GIVENS_X): sg.solver.add( PbEq([(Not(sg.cell_is(Point(y, x), SYM.X)), 1) for y in range(HEIGHT)], count)) for p, s in GIVENS.items(): sg.solver.add(sg.cell_is(p, s)) for p in LATTICE.points: shape_type = sc.shape_type_grid[p] shape_id = sc.shape_instance_grid[p] touching_types = [ n.symbol for n in LATTICE.vertex_sharing_neighbors(sc.shape_type_grid, p) ] touching_ids = [ n.symbol for n in LATTICE.vertex_sharing_neighbors( sc.shape_instance_grid, p) ] # Link the X symbol to the absence of a ship segment. sg.solver.add((sc.shape_type_grid[p] == -1) == sg.cell_is(p, SYM.X)) # Ship segments of different ships may not touch. and_terms = [] for touching_id in touching_ids: and_terms.append( Implies(shape_id >= 0, Or(touching_id == shape_id, touching_id == -1))) sg.solver.add(And(*and_terms)) # Choose the correct symbol for each ship segment. touching_count_terms = [(c == shape_type, 1) for c in touching_types] sg.solver.add( Implies(And(shape_type >= 0, PbEq(touching_count_terms, 2)), sg.cell_is(p, SYM.B))) sg.solver.add( Implies(And(shape_type >= 0, PbEq(touching_count_terms, 0)), sg.cell_is(p, SYM.O))) for n in sg.edge_sharing_neighbors(p): sg.solver.add( Implies( And(shape_type >= 0, PbEq(touching_count_terms, 1), sc.shape_type_grid[n.location] == shape_type), sg.cell_is(p, DIR_TO_OPPOSITE_SYM[n.direction]))) if sg.solve(): sg.print() print() sc.print_shape_instances() print() if sg.is_unique(): print("Unique solution") else: print("Alternate solution") sg.print() print() sc.print_shape_instances() print() else: print("No solution")
LetterColor.declare("letter_color", ("letter", IntSort()), ("color", IntSort())) LetterColor = LetterColor.create() def letter_color(letter: str, color: Color) -> ExprRef: """Creates a LetterColor z3 constant.""" return LetterColor.letter_color(SYM[letter], color.value) # type: ignore[attr-defined] SHAPES: List[Shape] = [ Shape([ (Vector(0, 1), letter_color("R", Color.BLUE)), (Vector(1, 0), letter_color("R", Color.BLUE)), (Vector(1, 1), letter_color("E", Color.BLUE)), (Vector(1, 2), letter_color("V", Color.BLUE)), (Vector(2, 1), letter_color("R", Color.BLUE)), ]), Shape([ (Vector(0, 0), letter_color("E", Color.WHITE)), (Vector(0, 1), letter_color("R", Color.WHITE)), (Vector(0, 2), letter_color("S", Color.YELLOW)), (Vector(1, 0), letter_color("A", Color.BLUE)), (Vector(1, 2), letter_color("O", Color.BLUE)), ]), Shape([ (Vector(0, 0), letter_color("C", Color.YELLOW)), (Vector(0, 1), letter_color("L", Color.YELLOW)), (Vector(1, 1), letter_color("F", Color.YELLOW)), (Vector(1, 2), letter_color("E", Color.BLUE)),