classSolution(object):defsolveSudoku(self, board):defgen_pos():for i in range(n):
for j in range(n):
yield i,j
defblock_id(i,j):return i//3*3+j//3defdelete(container,d):for item in container:
item.discard(d)
defrecover(container,initial):for item_c,item_ini in zip(container,initial):
item_c.clear()
item_c.update(item_ini)
defupdate():if len(cells)==0:returnTrue
(candidates,index) = min(((c,index) for index,c in cells.items()),key = lambda x:len(x[0]))
copy_candidates = candidates.copy()
if len(candidates)==0:returnFalse
row,col = index//9,index%9
block = row//3*3+col//3
copy_row = [cells[r].copy() for r in range(row*9,row*9+9) if r in cells]
copy_col = [cells[c].copy() for c in range(col,81,9) if c in cells]
copy_block = [cells[b].copy() for b in block_indexs[block] if b in cells]
for selected in copy_candidates:
delete((cells[r] for r in range(row*9,row*9+9) if r in cells),selected)
delete((cells[c] for c in range(col,81,9) if c in cells),selected)
delete((cells[b] for b in block_indexs[block] if b in cells),selected)
result_board[index//9][index%9] = selected
cells.pop(index)
ifnot update():
cells[index] = copy_candidates.copy()####fuck
recover((cells[r] for r in range(row*9,row*9+9) if r in cells),copy_row)
recover((cells[c] for c in range(col,81,9) if c in cells),copy_col)
recover((cells[b] for b in block_indexs[block] if b in cells),copy_block)
else:
returnTruereturnFalse
n = len(board)
all_num = {str(i+1) for i in range(n)}
rows = [all_num-set(row) for row in board]
cols = [all_num-set(col) for col in zip(*(row for row in board))]
blocks,block_indexs = [set() for i in range(n)],[[]for j in range(n)]
cells = [ [] for i in range(n*n) ]
result_board = [[s for s in row] for row in board]
for i,j in gen_pos():
index = block_id(i,j)
blocks[index].add(board[i][j])
block_indexs[index].append(i*9+j)
blocks = {index:all_num-item_set for index,item_set in enumerate(blocks) }
cells = {i*9+j:(rows[i]&cols[j]&blocks[block_id(i,j)]) \
for i,j in gen_pos() if board[i][j]=='.'}
update()
for i,(v1,v2) in enumerate(zip(board,result_board)):
board[i] = ''.join(v2)