Skip to content

Commit c51b4b7

Browse files
author
Hamid Gasmi
committed
Issue #141 is started
1 parent 4573a34 commit c51b4b7

File tree

1 file changed

+80
-0
lines changed

1 file changed

+80
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
import itertools
2+
import os
3+
4+
puzzle=[
5+
"5***1***4",
6+
"***2*6***",
7+
"**8*9*6**",
8+
"*4*****1*",
9+
"7*1*8*4*6",
10+
"*5*****3*",
11+
"**6*4*1**",
12+
"***5*2***",
13+
"2***6***8",
14+
]
15+
16+
clauses = []
17+
18+
digits = range(1, 10)
19+
20+
def varnum(i, j, k):
21+
assert(i in digits and j in digits and k in digits)
22+
return 100 * i + 10 * j + k
23+
24+
def exactly_one_of(literals):
25+
clauses.append([l for l in literals])
26+
27+
for pair in itertools.combinations(literals, 2):
28+
clauses.append([-l for l in pair])
29+
30+
# cell [i, j] contains exactly on digit
31+
for (i, j) in itertools.product(digits, repeat=2):
32+
exactly_one_of([varnum(i, j, k) for k in digits])
33+
34+
# k appears exactly once in row i
35+
for (i, k) in itertools.product(digits, repeat=2):
36+
exactly_one_of([varnum(i, j, k) for k in digits])
37+
38+
# k appears exactly once in column j
39+
for (j, k) in itertools.product(digits, repeat=2):
40+
exactly_one_of([varnum(i, j, k) for k in digits])
41+
42+
# k appears exactly once in a 3x3 block:
43+
for (i, j) in itertools.product([1, 4, 7], repeat=2):
44+
for k in digits:
45+
exactly_one_of([varnum(i + deltai, j + deltaj, k) for (deltai, deltaj) in itertools.product(range(3), repeat = 2)])
46+
47+
for (i, j) in itertools.product(digits, repeat=2):
48+
if puzzle[i - 1][j - 1] != "*":
49+
k = int(puzzle[i - 1][j - 1])
50+
assert(k in digits)
51+
#[i,j] already contains k:
52+
clauses.append(varnum(i, j, k))
53+
54+
with open('temp.cnf', 'w') as f:
55+
f.write("p cnf {} {}\n".format(999, len(clauses)))
56+
for c in clauses:
57+
c.append(0)
58+
f.write(" ".join(map(str, c))+"\n")
59+
60+
os.system("minisat tmp.cnf tmp.sat")
61+
62+
with open("tmp.sat", "r") as satfile:
63+
for line in satfile:
64+
if line.split()[0] == "UNSAT":
65+
print("There is no solution")
66+
67+
elif line.split()[0] == "SAT":
68+
pass
69+
70+
else:
71+
assignment = [int(x) for x in line.split()]
72+
73+
for i in digits:
74+
for j in digits:
75+
for k in digits:
76+
if varnum(i, j, k) in assignment:
77+
print(k, end="")
78+
break
79+
80+
print("")

0 commit comments

Comments
 (0)