# the "givens"
g =(
(5,3,0,0,7,0,0,0,0),
(6,0,0,1,9,5,0,0,0),
(0,9,8,0,0,0,0,6,0),
(8,0,0,0,6,0,0,0,3),
(4,0,0,8,0,3,0,0,1),
(7,0,0,0,2,0,0,0,6),
(0,6,0,0,0,0,2,8,0),
(0,0,0,4,1,9,0,0,5),
(0,0,0,0,8,0,0,7,9))
import pymprog
p = pymprog.model("sudoku")
I, J, K = range(9), range(9), range(1, 10)
T = pymprog.iprod(I,J,K) #create Indice tuples
x = p.var(T, 'x', bool)
#x[i,j,k] = 1 means cell [i,j] is assigned number k
#assign pre-defined numbers using the "givens"
p.st( [ +x[i,j,k] == (1 if g[i][j] == k else 0)
for (i,j,k) in T if g[i][j] > 0 ], 'given')
#each cell must be assigned exactly one number
p.st([sum(x[i,j,k] for k in K)==1 for i in I for j in J], 'cell')
#cells in the same row must be assigned distinct numbers
p.st([sum(x[i,j,k] for j in J)==1 for i in I for k in K], 'row')
#cells in the same column must be assigned distinct numbers
p.st([sum(x[i,j,k] for i in I)==1 for j in J for k in K], 'col')
#cells in the same region must be assigned distinct numbers
p.st([sum(x[i,j,k] for i in range(r,r+3) for j in range(c, c+3))==1
for r in range(0,9,3) for c in range(0,9,3) for k in K],'reg')
#there is no need for an objective function here
p.solve()
for i in I:
if i in range(0,9,3):
print " +-------+-------+-------+"
print '',
for j in J:
if j in range(0,9,3): print "|",
print "%g"%sum(x[i,j,k].primal*k for k in K),
if j==8: print "|"
if i == 8:
print " +-------+-------+-------+"