sp
4 weeks ago
6 changed files with 184 additions and 0 deletions
-
28Lecture2/colours-solution.py
-
13Lecture2/level0.txt
-
3Lecture2/level1.txt
-
17Lecture2/level2.txt
-
99Lecture2/maestria-in-class.py
-
24Lecture2/xkcd_287.py
@ -0,0 +1,28 @@ |
|||||
|
from itertools import combinations |
||||
|
from z3 import * |
||||
|
|
||||
|
solver = Solver() |
||||
|
|
||||
|
Colours = Datatype("Colours") |
||||
|
Colours.declare("RED") |
||||
|
Colours.declare("BLUE") |
||||
|
Colours.declare("GREEN") |
||||
|
Colours.declare("YELLOW") |
||||
|
|
||||
|
Colour = Colours.create() |
||||
|
f = Function('f', IntSort(), Colour) |
||||
|
|
||||
|
variables = list() |
||||
|
for i in range(0,5): |
||||
|
variables.append(Int(f"x{i}")) |
||||
|
solver.add(0 <= variables[-1]) |
||||
|
solver.add(variables[-1] <= 5) |
||||
|
|
||||
|
solver.add(Distinct(variables)) |
||||
|
|
||||
|
for combi in combinations(variables,2): |
||||
|
solver.add(Implies(Abs(combi[0] - combi[1]) == 1, f(combi[0]) != f(combi[1]))) |
||||
|
|
||||
|
result = solver.check() |
||||
|
if result == sat: |
||||
|
print(solver.model()) |
@ -0,0 +1,13 @@ |
|||||
|
XX_________________________________XX |
||||
|
_____________________________________ |
||||
|
________________1____________________ |
||||
|
_____________________________________ |
||||
|
_____________________________________ |
||||
|
_____________________________________ |
||||
|
_____________________________________ |
||||
|
_____________________________________ |
||||
|
_____________________________________ |
||||
|
_____________________________________ |
||||
|
_2_________________________________3_ |
||||
|
_____________________________________ |
||||
|
XX_________________________________XX |
@ -0,0 +1,3 @@ |
|||||
|
XXXXXXXX |
||||
|
X_1__3__ |
||||
|
X_2__4__ |
@ -0,0 +1,17 @@ |
|||||
|
XX___________________________XX |
||||
|
_______________________________ |
||||
|
_2___________________________3_ |
||||
|
_______________________________ |
||||
|
_______________________________ |
||||
|
_______________________________ |
||||
|
_______________________________ |
||||
|
_______________________________ |
||||
|
_______________________________ |
||||
|
_______________________________ |
||||
|
_______________________________ |
||||
|
_______________________________ |
||||
|
______________________1________ |
||||
|
_______________________________ |
||||
|
_______________________________ |
||||
|
_______________________________ |
||||
|
XX___________________________XX |
@ -0,0 +1,99 @@ |
|||||
|
# coding: utf-8 |
||||
|
import os, sys |
||||
|
from z3 import * |
||||
|
import string |
||||
|
# get the playground information |
||||
|
directory = os.path.dirname(os.path.realpath(__file__)) |
||||
|
fname = directory + "/" + "test0.txt" |
||||
|
|
||||
|
if len(sys.argv) == 2: |
||||
|
fname = sys.argv[1] |
||||
|
|
||||
|
with open(fname) as f: |
||||
|
playground = f.read() |
||||
|
playground = [[c for c in row] for row in 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) |
||||
|
for row in playground: |
||||
|
assert(len(row) == size_x) |
||||
|
|
||||
|
bells = {} |
||||
|
for i in range(size_y): |
||||
|
for j in range(size_x): |
||||
|
c = playground[i][j] |
||||
|
if ord(c) in range(ord("1"), ord("9") + 1): |
||||
|
assert(int(c) not in bells.keys()) |
||||
|
bells[int(c)] = (j, i) |
||||
|
|
||||
|
################################### Maestria ################################### |
||||
|
|
||||
|
|
||||
|
print(f"Playground size : {size_x} x {size_y}") |
||||
|
print("Playground:") |
||||
|
print("\n".join(["".join(i) for i in playground])) |
||||
|
print("Bell positions:") |
||||
|
print(bells) |
||||
|
print("\n") |
||||
|
|
||||
|
# create the solver |
||||
|
solver = Solver() |
||||
|
|
||||
|
fudge_x, fudge_y = Ints("fudge_x fudge_y") |
||||
|
|
||||
|
|
||||
|
# position must be in the board |
||||
|
solver.add(fudge_x >= 0, fudge_x < size_x, fudge_y >= 0, fudge_y < size_y) |
||||
|
|
||||
|
# position must be on walkable cell |
||||
|
for i in range(size_y): |
||||
|
for j in range(size_x): |
||||
|
if playground[i][j] != "_": |
||||
|
solver.add(Not(And(fudge_y == i, fudge_x == j))) |
||||
|
|
||||
|
# encode distances in formula |
||||
|
distances = {bell: None for bell in bells.keys()} |
||||
|
for bell, (x,y) in bells.items(): |
||||
|
distances[bell] = (fudge_x - x) * (fudge_x - x) + (fudge_y - y) * (fudge_y - y) |
||||
|
# |
||||
|
# enforce ordering of distances |
||||
|
distances_sorted = [distances[b] for b in sorted(bells.keys())] |
||||
|
for i in range(len(distances_sorted) - 1): |
||||
|
near = distances_sorted[i] |
||||
|
far = distances_sorted[i+1] |
||||
|
solver.add(near < far) |
||||
|
# call the solver and check satisfiability |
||||
|
while solver.check() == sat: |
||||
|
#result = solver.check() |
||||
|
#if result == sat: |
||||
|
m = solver.model() |
||||
|
if fudge_x is not None and fudge_y is not None: |
||||
|
pos_x = m[fudge_x].as_long() |
||||
|
pos_y = m[fudge_y].as_long() |
||||
|
playground[pos_y][pos_x] = "F" |
||||
|
solver.add(Or(fudge_x != pos_x, fudge_y != pos_y)) |
||||
|
|
||||
|
################################################################################ |
||||
|
|
||||
|
from colorama import Fore, Back, Style |
||||
|
|
||||
|
cols = [Fore.BLUE, Fore.GREEN, Fore.RED, Fore.YELLOW, Fore.MAGENTA, Fore.CYAN] |
||||
|
tones = [Style.BRIGHT, Style.DIM] |
||||
|
cols = sum([[c + t for c in cols] for t in tones], []) |
||||
|
|
||||
|
if sys.stdout.isatty(): |
||||
|
for bell in sorted(list(bells.keys())): |
||||
|
x, y = bells[bell] |
||||
|
playground[y][x] = Back.BLACK + cols[bell - 1] + playground[y][x] + Style.RESET_ALL |
||||
|
for y in range(size_y): |
||||
|
for x in range(size_x): |
||||
|
c = playground[y][x] |
||||
|
if c == "_": playground[y][x] = Fore.BLACK + Back.WHITE + c + Style.RESET_ALL |
||||
|
if c == "X": playground[y][x] = Fore.WHITE + Back.BLACK + c + Style.RESET_ALL |
||||
|
if c == "F": playground[y][x] = Fore.BLACK + Back.WHITE + c + Style.RESET_ALL |
||||
|
|
||||
|
text = "\n".join(["".join([c for c in row]) for row in playground]) |
||||
|
print(text) |
@ -0,0 +1,24 @@ |
|||||
|
#!/usr/bin/python3 |
||||
|
|
||||
|
from z3 import * |
||||
|
|
||||
|
a,b,c,d,e,f = Ints('a b c d e f') |
||||
|
s = Solver() |
||||
|
s.add(215*a + 275*b + 335*c + 355*d + 420*e + 580*f == 1505, a>=0, b>=0, c>=0, d>=0, e>=0, f>=0) |
||||
|
|
||||
|
results=[] |
||||
|
while True: |
||||
|
if s.check() == sat: # |
||||
|
m = s.model() # |
||||
|
print(m) # |
||||
|
results.append(m) |
||||
|
#block = [a != m[a].as_long(), b != m[b].as_long(), c != m[c].as_long(), d != m[d].as_long(), e != m[e].as_long(), f != m[f].as_long()] |
||||
|
#Different approach: Iterate over all entries in the model |
||||
|
block = [] |
||||
|
for d in m.decls(): |
||||
|
#print(d, type(d), d(), type(d()), m[d], type(m[d])) |
||||
|
block.append(d() != m[d].as_long()) |
||||
|
s.add(Or(block)) |
||||
|
else: |
||||
|
print ("All results enumerated, total =", len(results)) |
||||
|
break |
Write
Preview
Loading…
Cancel
Save
Reference in new issue