forked from sp/lub2022-practical
				
			
				 5 changed files with 150 additions and 0 deletions
			
			
		| @ -0,0 +1,3 @@ | |||
| .10 | |||
| 0T? | |||
| 1?? | |||
| @ -0,0 +1,4 @@ | |||
| .1011 | |||
| 1T??? | |||
| 1???T | |||
| 1???T | |||
| @ -0,0 +1,7 @@ | |||
| .301111 | |||
| 1T????? | |||
| 1??TT?? | |||
| 2???T?? | |||
| 1?T???? | |||
| 1?????? | |||
| 1?T???T | |||
| @ -0,0 +1,7 @@ | |||
| .021211 | |||
| 2?T?T?? | |||
| 0???T?? | |||
| 2T????? | |||
| 0?????T | |||
| 3?????? | |||
| 0?T?T?? | |||
| @ -0,0 +1,129 @@ | |||
| # coding: utf-8 | |||
| import os, sys | |||
| from z3 import * | |||
| 
 | |||
| # get the playground information | |||
| if len(sys.argv) != 2: | |||
|     print("Usage: python3 trees_and_tents.py <forest-file>") | |||
| 
 | |||
| EMPTY = "?" | |||
| TREE = 2 | |||
| 
 | |||
| if len(sys.argv) == 2: | |||
|     fname = sys.argv[1] | |||
| 
 | |||
| with open(fname) as f: | |||
|     playground = f.read() | |||
|     cols = [col for col in playground.strip().split("\n")[0][1:]] | |||
|     rows = [row[0] for row in playground.strip().split("\n")[1:]] | |||
| playground = [[EMPTY if x == EMPTY else x for x in row[1:]] | |||
|         for row in playground.strip().split("\n")[1:]] | |||
| 
 | |||
| # get the playground size | |||
| len_rows = len(rows) | |||
| assert(len_rows != 0) | |||
| len_cols = len(cols) | |||
| assert(len_cols != 0) | |||
| 
 | |||
| def print_result(model): | |||
|     print("  " + ''.join(cols) + " "*5 + ''.join(cols)) | |||
|     for i in range(len_rows): | |||
|         print(rows[i] + " " + ''.join(playground[i]) + " >>> ", end='') | |||
|         for j in range(len_cols): | |||
|             cell = model[cells[i][j]].as_long() | |||
|             if cell != TREE: | |||
|                 print(cell, end='') | |||
|             elif cell == TREE: | |||
|                 print("T", end='') | |||
|         print() | |||
| 
 | |||
| def print_forest(): | |||
|     print("  " + ''.join(cols)) | |||
|     for i in range(len_rows): | |||
|         print(rows[i] + " ", end='') | |||
|         for j in range(len_cols): | |||
|             cell = playground[i][j] | |||
|             if cell != TREE: | |||
|                 print(cell, end='') | |||
|             elif cell == TREE: | |||
|                 print("T", end='') | |||
|         print() | |||
| 
 | |||
| ################################# Trees and Tents ################################## | |||
| # create the solver | |||
| solver = Solver() | |||
| cells = [[None for j in range(len_cols)] for i in range(len_rows)] | |||
| 
 | |||
| def get_possible_tents_in_col(col): | |||
|     possible_tent_positions = [] | |||
|     for row in range(len_rows): | |||
|         if playground[row][col] != "T": | |||
|            possible_tent_positions.append(cells[row][col]) | |||
|     return possible_tent_positions | |||
| 
 | |||
| def get_possible_tents_in_row(row): | |||
|     possible_tent_positions = [] | |||
|     for col in range(len_cols): | |||
|         if playground[row][col] != "T": | |||
|            possible_tent_positions.append(cells[row][col]) | |||
|     return possible_tent_positions | |||
| 
 | |||
| def get_neighbours(i, j): | |||
|     cs = [] | |||
|     for p in range(max(i-1, 0), min(i+2, len_rows)): | |||
|         for q in range(max(j-1, 0), min(j+2, len_cols)): | |||
|             if p == i and q == j: continue | |||
|             cs.append(cells[p][q]) | |||
|     return cs | |||
| 
 | |||
| def get_tree_neighbours(i, j): | |||
|     tree_pos = [] | |||
|     for p in [max(i-1, 0), min(i+1, len_rows - 1)]: | |||
|         if p == i: continue | |||
|         tree_pos.append(cells[p][j]) | |||
|     for q in [max(j-1, 0), min(j+1, len_cols - 1)]: | |||
|         if q == j: continue | |||
|         tree_pos.append(cells[i][q]) | |||
|     return tree_pos | |||
| 
 | |||
| # TODO | |||
| # Cell entries need to be represented by a Z3 variable | |||
| for i in range(len_rows): | |||
|     for j in range(len_cols): | |||
|     #   your code goes here... | |||
| # TODO | |||
| # Bound/restrict the values of the cells according to the input | |||
|         if playground[i][j] == EMPTY: | |||
|         #   your code goes here... | |||
|         else: | |||
|         #   your code goes here... | |||
| 
 | |||
| # TODO | |||
| # The sums of tents per row/column must match the amounts given in the input | |||
| for j in range(len_cols): | |||
| #   your code goes here... | |||
| for i in range(len_rows): | |||
| #   your code goes here... | |||
| 
 | |||
| for i in range(len_rows): | |||
|     for j in range(len_cols): | |||
|         if playground[i][j] == "T": continue | |||
|         tree_constraint = Bool("False") | |||
|         # TODO | |||
|         # A tent needs to be next to a tree | |||
|         # Incrementally build up the tree_constraint ... | |||
|         for possible_tree in get_tree_neighbours(i, j): | |||
|         #   your code goes here... | |||
|         # ... and add it to the solver | |||
|         # TODO | |||
|         # A tent must not be next to another tent | |||
|         for neighbour in get_neighbours(i, j): | |||
|         #   your code goes here... | |||
| 
 | |||
| res = solver.check() | |||
| if res == unsat: | |||
|     print("UNSAT") | |||
|     print_forest() | |||
| else: | |||
|     m = solver.model() | |||
|     print_result(m) | |||
						Write
						Preview
					
					
					Loading…
					
					Cancel
						Save
					
		Reference in new issue