sudoku.py

# 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 " +-------+-------+-------+"