sp
2 years ago
2 changed files with 274 additions and 0 deletions
@ -0,0 +1,114 @@ |
|||||
|
# coding: utf-8 import os, sys |
||||
|
from z3 import * |
||||
|
|
||||
|
# get the playground information |
||||
|
if len(sys.argv) != 2: |
||||
|
print("Usage: python3 colours.py <map-file>") |
||||
|
sys.exit(0) |
||||
|
|
||||
|
with open(sys.argv[1]) as f: |
||||
|
playground = f.read() |
||||
|
playground = playground.strip().split("\n") |
||||
|
|
||||
|
# get the playground size |
||||
|
size_y = len(playground) |
||||
|
assert(size_y != 0) |
||||
|
size_x = len(playground[0]) |
||||
|
assert(size_x != 0) |
||||
|
assert(all([len(p) == size_x for p in playground])) |
||||
|
# get the number of regions |
||||
|
regions = set("".join(playground)) |
||||
|
|
||||
|
################################### Colours #################################### |
||||
|
|
||||
|
# create the solver |
||||
|
solver = Solver() |
||||
|
|
||||
|
# todo: create a datatype Colour |
||||
|
# ... |
||||
|
# todo: declare four valid colours |
||||
|
# ... |
||||
|
# hint: don't forget to call "create" for the datatype to get a Sort |
||||
|
# ... |
||||
|
|
||||
|
# todo: create a colour variable for each playground cell |
||||
|
# hint: you can do this with Const("var_name", YourSort) |
||||
|
# hint: use something like the coordinates as part of the variable name |
||||
|
p_colours = [[None for _j in range(size_x)] for _j in range(size_y)] |
||||
|
for i in range(size_y): |
||||
|
for j in range(size_x): |
||||
|
# p_colours[i][j] = ... replace this with your code |
||||
|
pass |
||||
|
|
||||
|
print("All regions found in this map: '{}'.".format(",".join(regions))) |
||||
|
for r in regions: |
||||
|
# todo: find all cells that belong to the same region |
||||
|
region_vars = [] |
||||
|
for i in range(size_y): |
||||
|
for j in range(size_x): |
||||
|
pass # ... add the variable to region_vars here |
||||
|
|
||||
|
# todo: make all colours in the same region identical |
||||
|
# hint: use the transitivitiy of equality x1 = x2 & x2 = x3 -> x1 = x3 |
||||
|
for c in range(len(region_vars) - 1): |
||||
|
pass # ... replace this with your code ... |
||||
|
|
||||
|
|
||||
|
def get_neighbours(i, j): |
||||
|
regions = [] |
||||
|
colours = [] |
||||
|
if i > 0: |
||||
|
colours.append( p_colours[i-1][j]) |
||||
|
regions.append(playground[i-1][j]) |
||||
|
if i < size_y - 1: |
||||
|
colours.append( p_colours[i+1][j]) |
||||
|
regions.append(playground[i+1][j]) |
||||
|
if j > 0: |
||||
|
colours.append( p_colours[i][j-1]) |
||||
|
regions.append(playground[i][j-1]) |
||||
|
if j < size_x - 1: |
||||
|
colours.append( p_colours[i][j+1]) |
||||
|
regions.append(playground[i][j+1]) |
||||
|
return zip(regions, colours) |
||||
|
|
||||
|
|
||||
|
# todo: if two neighboring cells are from different regions |
||||
|
# then they must have different colours |
||||
|
for i in range(size_y): |
||||
|
for j in range(size_x): |
||||
|
cell_r = playground[i][j] |
||||
|
cell_c = p_colours[i][j] |
||||
|
for r, c in get_neighbours(i, j): |
||||
|
pass # ... replace this with your code ... |
||||
|
|
||||
|
# call the solver and check satisfiability |
||||
|
res = solver.check() |
||||
|
if res != sat: |
||||
|
print("unsat") |
||||
|
sys.exit(1) |
||||
|
|
||||
|
# todo make a translation to strings "1", "2", "3", "4" |
||||
|
def translate(s): |
||||
|
# hint: do something analogouns to the following line here |
||||
|
# if s.sexpr() == "C1": return "1" |
||||
|
# ... |
||||
|
return "0" |
||||
|
|
||||
|
################################################################################ |
||||
|
|
||||
|
from colorama import Fore, Back, Style |
||||
|
cols = [Back.BLACK, Back.RED, Back.GREEN, Back.BLUE, Back.MAGENTA] |
||||
|
cols = [Style.BRIGHT + Fore.WHITE + c for c in cols] |
||||
|
|
||||
|
# print the model as translated numbers |
||||
|
m = solver.model() |
||||
|
names = [x.name() for x in m.decls()] |
||||
|
for i in range(size_y): |
||||
|
row = "" |
||||
|
for j in range(size_x): |
||||
|
pc = p_colours[i][j] |
||||
|
invalid = (pc is None or pc.decl() not in m.decls()) |
||||
|
t = "0" if invalid else translate(m[pc]) |
||||
|
if sys.stdout.isatty(): t = cols[int(t)] + t + Style.RESET_ALL |
||||
|
row += t |
||||
|
print(row) |
@ -0,0 +1,160 @@ |
|||||
|
# coding: utf-8 |
||||
|
import os, sys |
||||
|
from z3 import * |
||||
|
|
||||
|
from itertools import combinations |
||||
|
|
||||
|
pretty_print = True |
||||
|
|
||||
|
# get the playground information |
||||
|
if len(sys.argv) != 2: |
||||
|
print("Usage: python3 seating-arrangement.py <wedding-file>") |
||||
|
sys.exit(0) |
||||
|
|
||||
|
def faulty_line(line, num): |
||||
|
print("Faulty input at line " + str(num) + ". Ignoring '" + line + "'") |
||||
|
|
||||
|
# data structures prepared for you |
||||
|
guests = set() |
||||
|
friends = [] |
||||
|
foes = [] |
||||
|
longest_name_len = 0 |
||||
|
|
||||
|
def add_to_guest_list(a,b=None): |
||||
|
guests.add(a) |
||||
|
if b != None: |
||||
|
guests.add(b) |
||||
|
|
||||
|
def longest_name(a,b=None): |
||||
|
global longest_name_len |
||||
|
if len(a) > longest_name_len: longest_name_len = len(a) |
||||
|
if b != None and len(b) > longest_name_len : longest_name_len = len(b) |
||||
|
|
||||
|
solver = Solver() |
||||
|
|
||||
|
################################### Parse Guests and Constraints #################################### |
||||
|
|
||||
|
Guest = DeclareSort("Guest") |
||||
|
|
||||
|
with open(sys.argv[1]) as f: |
||||
|
wedding = f.read() |
||||
|
wedding = wedding.strip().split("\n") |
||||
|
linenum = 0 |
||||
|
for line in wedding: |
||||
|
linenum += 1 |
||||
|
if line[0] == '#': |
||||
|
continue |
||||
|
if line.rstrip(): |
||||
|
info = line.split(" ") |
||||
|
|
||||
|
if len(info) == 1: |
||||
|
guest = Const(info[0], Guest) |
||||
|
add_to_guest_list() |
||||
|
longest_name(info[0]) |
||||
|
continue |
||||
|
|
||||
|
if len(info) != 3: |
||||
|
faulty_line(line, linenum) |
||||
|
continue |
||||
|
|
||||
|
longest_name(info[0], info[2]) |
||||
|
if info[1] == "dislikes": |
||||
|
first_guest = Const(info[0], Guest) |
||||
|
second_guest = Const(info[2], Guest) |
||||
|
add_to_guest_list(first_guest, second_guest) |
||||
|
# todo add the pair of guests as foes |
||||
|
elif info[1] == "likes": |
||||
|
first_guest = Const(info[0], Guest) |
||||
|
second_guest = Const(info[2], Guest) |
||||
|
add_to_guest_list(first_guest, second_guest) |
||||
|
# todo add pair of guests as friends |
||||
|
else: |
||||
|
faulty_line(line, linenum) |
||||
|
continue |
||||
|
|
||||
|
################################### Wedding Guests #################################### |
||||
|
|
||||
|
# todo create an uninterpreted function from the Guest sort to an IntSort() |
||||
|
|
||||
|
# todo create a function which returns whether two guests are sitting next to each other |
||||
|
def neigbours(a, b): |
||||
|
pass |
||||
|
|
||||
|
# todo all guests must be seated at the big table |
||||
|
# check the indices here |
||||
|
for guest in guests: |
||||
|
pass |
||||
|
|
||||
|
# todo no two guests should sit on the same position |
||||
|
for combination in combinations(guests,2): #todo |
||||
|
pass |
||||
|
|
||||
|
#todo friends should be neigbours |
||||
|
for (a,b) in friends: #todo |
||||
|
pass |
||||
|
|
||||
|
#todo foes should not be neigbours |
||||
|
for (a,b) in foes: # todo |
||||
|
pass |
||||
|
|
||||
|
# check satisfiability |
||||
|
res = solver.check() |
||||
|
if res != sat: |
||||
|
print("unsat") |
||||
|
sys.exit(1) |
||||
|
m = solver.model() |
||||
|
|
||||
|
################################################################################ |
||||
|
|
||||
|
|
||||
|
arrangement = ["" for guest in range(len(guests))] |
||||
|
for guest in guests: |
||||
|
arrangement[m.evaluate(position(guest),model_completion=True).as_long()] = guest.decl().name() |
||||
|
|
||||
|
def print_table(): |
||||
|
side_length = round(len(guests)/4) |
||||
|
top = arrangement[0:side_length] |
||||
|
right = arrangement[side_length:2*side_length] |
||||
|
bottom = arrangement[2*side_length:3*side_length] |
||||
|
left = arrangement[3*side_length:] |
||||
|
while len(left) < len(right): |
||||
|
left.append("") |
||||
|
while len(right) < len(left): |
||||
|
right.append("") |
||||
|
table_line_length = longest_name_len + 1 |
||||
|
|
||||
|
print("\n") |
||||
|
|
||||
|
top_row = "" |
||||
|
top_row += (longest_name_len + 1) * " " |
||||
|
for top_guest in top: |
||||
|
top_row += top_guest + " " |
||||
|
table_line_length += len(top_guest) + 1 |
||||
|
print(top_row) |
||||
|
print((longest_name_len + 1) * " " + table_line_length * "-") |
||||
|
|
||||
|
first_element = True |
||||
|
for left_guest, right_guest in zip(reversed(left), right): |
||||
|
row = "" |
||||
|
if not first_element: |
||||
|
row += longest_name_len * " " |
||||
|
row += "|" + ">"* (table_line_length) + "|" |
||||
|
print(row) |
||||
|
row = "" |
||||
|
else: |
||||
|
first_element = False |
||||
|
row += left_guest.rjust(longest_name_len) + "|" + "<"* (table_line_length) + "|" + right_guest |
||||
|
print(row) |
||||
|
|
||||
|
print((longest_name_len + 1) * " " + table_line_length * "-") |
||||
|
bottom_row = "" |
||||
|
bottom_row += (longest_name_len + 1) * " " |
||||
|
for bottom_guest in reversed(bottom): |
||||
|
bottom_row += bottom_guest + " " |
||||
|
print(bottom_row) |
||||
|
print("\n") |
||||
|
|
||||
|
if(pretty_print): |
||||
|
print_table() |
||||
|
print("Seating plan:") |
||||
|
print(arrangement) |
Write
Preview
Loading…
Cancel
Save
Reference in new issue