-
Notifications
You must be signed in to change notification settings - Fork 1
/
prob-sudoku.py
147 lines (111 loc) · 3.12 KB
/
prob-sudoku.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
#!/usr/bin/python3
from z3 import *
import argparse
import itertools
import time
problem1 = [
[ 9, 0, 0, 0, 1, 0, 5, 0, 0],
[ 7, 0, 0, 8, 0, 3, 0, 0, 2],
[ 0, 0, 0, 0, 0, 0, 3, 0, 8],
[ 0, 7, 8, 0, 2, 5, 6, 0, 0],
[ 0, 0, 0, 0, 0, 0, 0, 0, 0],
[ 0, 0, 2, 3, 4, 0, 1, 8, 0],
[ 8, 0, 9, 0, 0, 0, 0, 0, 0],
[ 5, 0, 0, 4, 0, 1, 0, 0, 9],
[ 0, 0, 1, 0, 5, 0, 0, 0, 4]
]
problem2 = [
[ 0, 8, 0, 0, 0, 3, 0, 0, 0],
[ 5, 0, 3, 0, 4, 0, 2, 0, 0],
[ 7, 0, 4, 0, 8, 0, 0, 0, 3],
[ 0, 7, 0, 0, 0, 0, 5, 0, 0],
[ 0, 3, 0, 8, 0, 5, 0, 6, 0],
[ 0, 0, 1, 0, 0, 0, 0, 9, 0],
[ 9, 0, 0, 0, 3, 0, 7, 0, 6],
[ 0, 0, 7, 0, 2, 0, 3, 0, 1],
[ 0, 0, 0, 6, 0, 0, 0, 2, 0]
]
problem3 = [
[ 7, 0, 0, 8, 0, 5, 0, 0, 6],
[ 0, 0, 4, 0, 6, 0, 2, 0, 0],
[ 0, 5, 0, 2, 0, 4, 0, 9, 0],
[ 8, 0, 5, 0, 0, 0, 3, 0, 9],
[ 0, 1, 0, 0, 0, 0, 0, 6, 0],
[ 3, 0, 6, 0, 0, 0, 1, 0, 7],
[ 0, 6, 0, 5, 0, 7, 0, 1, 0],
[ 0, 0, 7, 0, 9, 0, 6, 0, 0],
[ 5, 0, 0, 3, 0, 6, 0, 0, 2]
]
problem = problem1
# problem = problem2
# define the problem variables
# Hint: three dimentional array
arr=[[[Bool('p'+str(i)+str(j)+str(k)) for k in range(1,10)] for j in range(1,10)] for i in range(1,10)]
def sum_to_one( ls ):
phi1=Or(ls)
l=[Or(Not(p),Not(q)) for i,p in enumerate(ls) for j,q in enumerate(ls) if i !=j]
phi2=And(l)
phi3=And(phi1,phi2)
return phi3
# def sum_to_one( ls ):
# reuse some to one code
# Accumulate constraints in the following list
Fs1 = [sum_to_one(arr[i][j]) for i in range(9) for j in range(9)]
Fs2=[]
for j in range(9):
for k in range(9):
l=[]
for i in range(9):
l=l+[arr[i][j][k]]
Fs2=Fs2+[sum_to_one(l)]
Fs3=[]
for i in range(9):
for k in range(9):
l=[]
for j in range(9):
l=l+[arr[i][j][k]]
Fs3=Fs3+[sum_to_one(l)]
Fs4=[]
for i in range(0,3):
for j in range(0,3):
for k in range(9):
l=[]
for r in range(0,3):
for s in range(0,3):
l=l+[arr[3*i+r][3*j+s][k]]
Fs4=Fs4+[sum_to_one(l)]
Fs=Fs1+Fs2+Fs3+Fs4
Fs5=[]
for i in range(9):
for j in range(9):
if not(problem[i][j]==0):
# p=Bool("p")
# p=True
Fs5=[arr[i][j][problem[i][j]-1]]+Fs5
Fs=Fs+Fs5
# Encode already filled positions
# Encode for i,j \sum_k x_i_j_k = 1
# Encode for j,k \sum_i x_i_j_k = 1
# Encode for i,k \sum_j x_i_j_k = 1
# Encode for i,j,k \sum_r_s x_3i+r_3j+s_k = 1
s = Solver()
s.add( And( Fs ) )
if s.check() == sat:
m = s.model()
for i in range(9):
if i % 3 == 0 :
print("|-------|-------|-------|")
for j in range(9):
if j % 3 == 0 :
print ("|", end =" ")
for k in range(9):
# FILL THE GAP
# val model for the variables
val = m[arr[i][j][k]]
if is_true( val ):
print("{}".format(k+1), end =" ")
print("|")
print("|-------|-------|-------|")
else:
print("sudoku is unsat")
# print vars