Problems:
https://leetcode.com/problems/valid-sudoku/
https://leetcode.com/problems/sudoku-solver/
Validate a sudoku puzzle. Here given puzzle might not be valid and unsolved.
Need to just make sure that it is a valid puzzle.
Entire poblem is just invested in :{validate each row, validate each column and validate each grid}
Finding individual grid to validate can be tricky for beginners
'''
given any index i, j in the 9x9 board
this function will baseline itself to
grid base left and upper most index
and do the 3x3 grid validation.
'''
def gridvalidator(i, j,board):
k = i//3 #gives the base row
l = j//3 #gives the base column
#now grid boundary exist between x:{k*3+[0,3)} y:{l*3+[0,3)}
cache=defaultdict(lambda:False)
for m in range(0,3):
for n in range(0,3):
if board[k*3+m][l*3+n] != ".":
if cache[board[k*3+m][l*3+n]]:
return False
cache[board[k*3+m][l*3+n]] = True
return TrueFull solution is here:
class Solution:
def isValidSudoku(self, board: List[List[str]]) -> bool:
'''
1. given any index i, j in the 9x9 board
this function will baselines itself to
grid base left and upper most index
and do the 3x3 grid validation.
'''
def gridvalidator(i, j,board):
k = i//3 #gives the base row
l = j//3 #gives the base column
#now grid boundary exist between x:[k*3+[0,3)] y:[l*3+[0,3)]
cache=defaultdict(lambda:False)
for m in range(0,3):
for n in range(0,3):
if board[k*3+m][l*3+n] != ".":
if cache[board[k*3+m][l*3+n]]:
return False
cache[board[k*3+m][l*3+n]] = True
return True
def columnvalidator(j, board):
cache=defaultdict(lambda:False)
for i in range(9):
if board[i][j] != ".":
if cache[board[i][j]]:
return False
cache[board[i][j]] = True
return True
def rowvalidator(i, board):
cache=defaultdict(lambda:False)
for j in range(9):
if board[i][j] != ".":
if cache[board[i][j]]:
return False
cache[board[i][j]] = True
return True
#pass only the grid base index
i = 0
while i < 9:
j=0
while j < 9:
if gridvalidator(i,j,board) == False:
return False
j+=3
i+=3
#pass each column index
j = 0
while j < 9:
if columnvalidator(j, board) == False:
return False
j+=1
i = 0
while i < 9:
if rowvalidator(i, board) == False:
return False
i+=1
return TrueSudoku solver: Given a valid sudoku solve the puzzle
Unlike validator here backtracking is needed.
Reuse the recipies of colum, row and grid but this time to generate candidates for
filling the puzzle.
def columncandidates(j,s,board):
for i in range(9):
if board[i][j] != "." and board[i][j] in s:
s.remove(str(board[i][j]))
return True
def rowcandidates(i,s,board):
for j in range(9):
if board[i][j] != "." and board[i][j] in s:
s.remove(str(board[i][j]))
return True
def gridcandidates(i,j,s,board):
k = i//3 #gives the base row
l = j//3 #gives the base column
#now grid boundary exist between x:[k*3+[0,3)] y:[l*3+[0,3)]
for m in range(0,3):
for n in range(0,3):
if board[k*3+m][l*3+n] != "." and board[k*3+m][l*3+n] in s:
s.remove(board[k*3+m][l*3+n])
return TrueFull solution:
class Solution:
def solveSudoku(self, board: List[List[str]]) -> None:
"""
Do not return anything, modify board in-place instead.
"""
def columncandidates(j,s,board):
for i in range(9):
if board[i][j] != "." and board[i][j] in s:
s.remove(str(board[i][j]))
return True
def rowcandidates(i,s,board):
for j in range(9):
if board[i][j] != "." and board[i][j] in s:
s.remove(str(board[i][j]))
return True
def gridcandidates(i,j,s,board):
k = i//3 #gives the base row
l = j//3 #gives the base column
#now grid boundary exist between x:[k*3+[0,3)] y:[l*3+[0,3)]
for m in range(0,3):
for n in range(0,3):
if board[k*3+m][l*3+n] != "." and board[k*3+m][l*3+n] in s:
s.remove(board[k*3+m][l*3+n])
return True
def dfs(i,j,board):
if i == 9:
return True
while board[i][j] != ".":
if j == 8:
i+=1
j=0
else:
j+=1
if i > 8:
return True
s=set([str(_) for _ in range(1,10)])
columncandidates(j,s,board)
rowcandidates(i,s,board)
gridcandidates(i,j,s,board)
for cand in s:
board[i][j] = cand
if j == 8:
row = i+1
col = 0
else:
row = i
col = j+1
if dfs(row, col,board) == True:
return True
board[i][j] = "."
return False
dfs(0,0,board)
return board