import math
class Solution(object):
def mask(self, box, i, j):
v=(1<<9)-1
for i0 in xrange((i/3)*3, (i/3)*3+3):
for j0 in xrange((j/3)*3, (j/3)*3+3):
v&=~box[(i0,j0)]
for i0 in xrange(0, 9):
v&=~box[(i0,j)]
v&=~box[(i,i0)]
return v
def solveSudoku(self, board):
"""
:type board: List[List[str]]
:rtype: bool
"""
box={}
box2={}
assume=[]
for i,line in enumerate(board):
for j,c in enumerate(line):
box[(i,j)]=0
if c!='.':
box[(i,j)]=(1<<(int(c)-1))
else:
box2[(i,j)]=(1<<9)-1
self.dump("init:", box)
while True:
renew = True
while renew:
resolved=1
for i in xrange(0,9):
for j in xrange(0,9):
if box[(i,j)]!=0:
continue
resolved=0
box2[(i,j)]=self.mask(box, i, j)
renew=False
for i in xrange(0,9):
if resolved==2: break
for j in xrange(0,9):
if box[(i,j)]!=0:
continue
if box2[(i,j)] == 0:
resolved=2
break
if (~box2[(i,j)]+1)&box2[(i,j)] == box2[(i,j)]:
box[(i,j)]=box2[(i,j)]
renew=True
break
if resolved==1:
break
self.dump("step:%d,%d"%( resolved, len(assume)), box)
if resolved==2:
while len(assume)>0:
i,j,lastv,box = assume[-1]
box2[(i,j)]=self.mask(box, i, j)
remain=(box2[(i,j)]/lastv-1)*lastv
newv=(~(remain)+1)&remain
if newv>0:
assume[-1]=(i,j,newv,box.copy())
box[(i,j)]=newv
break
del assume[-1]
if resolved==0:
for i in xrange(0,9):
for j in xrange(0,9):
if box[(i,j)]==0:
break
if box[(i,j)]==0:
break
self.dump("before assume:", box)
loop=True
dumpbox=box.copy()
box[(i,j)]=(~box2[(i,j)]+1)&box2[(i,j)]
assume.append((i,j,box[(i,j)], dumpbox))
self.dump("after assume:", box)
self.dump("final:", box)
for i in xrange(0,9):
for j in xrange(0,9):
if box[(i,j)]>0:
board[i][j]=str(int(math.log(box[(i,j)],2))+1)
return True
def dump(self, info, box):
return
print info
for i in xrange(9):
for j in xrange(9):
if box[(i,j)] == 0:
print '.',
else: print int(math.log(box[(i,j)], 2)+1),
print