Determine if a 9x9 Sudoku board is valid. Only the filled cells need to be validated according to the following rules:


       Each row must contain the digits 1-9 without repetition.
       Each column must contain the digits 1-9 without repetition.
       Each of the 9 3x3 sub-boxes of the grid must contain the digits 1-9 without repetition.



A partially filled sudoku which is valid.

The Sudoku board could be partially filled, where empty cells are filled with the character '.'.

Example 1:


Input:
[
  ["5","3",".",".","7",".",".",".","."],
  ["6",".",".","1","9","5",".",".","."],
  [".","9","8",".",".",".",".","6","."],
  ["8",".",".",".","6",".",".",".","3"],
  ["4",".",".","8",".","3",".",".","1"],
  ["7",".",".",".","2",".",".",".","6"],
  [".","6",".",".",".",".","2","8","."],
  [".",".",".","4","1","9",".",".","5"],
  [".",".",".",".","8",".",".","7","9"]
]
Output: true


Example 2:


Input:
[
  ["8","3",".",".","7",".",".",".","."],
  ["6",".",".","1","9","5",".",".","."],
  [".","9","8",".",".",".",".","6","."],
  ["8",".",".",".","6",".",".",".","3"],
  ["4",".",".","8",".","3",".",".","1"],
  ["7",".",".",".","2",".",".",".","6"],
  [".","6",".",".",".",".","2","8","."],
  [".",".",".","4","1","9",".",".","5"],
  [".",".",".",".","8",".",".","7","9"]
]
Output: false
Explanation: Same as Example 1, except with the 5 in the top left corner being 
    modified to 8. Since there are two 8's in the top left 3x3 sub-box, it is invalid.


Note:


       A Sudoku board (partially filled) could be valid but is not necessarily solvable.
       Only the filled cells need to be validated according to the mentioned rules.
       The given board contain only digits 1-9 and the character '.'.
       The given board size is always 9x9.

Difficulty: interview

Starter code:

class Solution:
    def isValidSudoku(self, board: List[List[str]]) -> bool:
        

Solutions:
class Solution:
     def isValidSudoku(self, board):
         """
         :type board: List[List[str]]
         :rtype: bool
         """
         dic_row = [{},{},{},{},{},{},{},{},{}]
         dic_col = [{},{},{},{},{},{},{},{},{}]
         dic_box = [{},{},{},{},{},{},{},{},{}]
 
         for i in range(len(board)):
             for j in range(len(board)):
                 num = board[i][j]
                 if num == ".":
                     continue
                 if num not in dic_row[i] and num not in dic_col[j] and num not in dic_box[3*(i//3)+(j//3)]:
                     dic_row[i][num] = 1
                     dic_col[j][num] = 1
                     dic_box[3*(i//3)+(j//3)][num] = 1
                 else:
                     return False
 
         return True
             


class Solution:
     
     
     def isValidSudoku(self, board):
         """
         :type board: List[List[str]]
         :rtype: bool
         """
         row_dict={}
         col_dict={}
         ssq_dict={}
 
         for row in range(len(board)):
             for col in range(len(board[0])):
                 if board[row][col]!='.':
                     if 'r'+str(row) not in row_dict:
                         row_dict['r'+str(row)]=[board[row][col]]
                     else:
                         row_dict['r'+str(row)].append(board[row][col])
 
                     if 'c'+str(col) not in col_dict:
                         col_dict['c'+str(col)]=[board[row][col]]
                     else:
                         col_dict['c'+str(col)].append(board[row][col])
                     if 's'+str(row-row%3)+ str(col-col%3) not in ssq_dict:
                         print('s'+str(row-row%3)+ str(col-col%3))
                         ssq_dict['s'+str(row-row%3)+ str(col-col%3)]=[board[row][col]]
                     else:
                         ssq_dict['s'+str(row-row%3)+ str(col-col%3)].append(board[row][col])
 
                         
         for val in row_dict.values():
             if len(val)>len(set(val)):
                 return False
 
         for val in col_dict.values():
             if len(val)>len(set(val)):
                 return False
         for val in ssq_dict.values():
             if len(val)>len(set(val)):
                 return False          
         return True

class Solution:    
     def repeat(self, val, seen):
             print((val, seen))
             return seen >> int(val) & 1
 
     def isValidSudoku(self, board):
         """
         :type board: List[List[str]]
         :rtype: bool
         """
         seen = set()
         for i in range(9):
             for j in range(9):
                 if board[i][j].isdigit():
                     val = board[i][j]
                     row = (i, val)
                     col = (val, j)
                     box = (i//3, j//3, val)
                     if row in seen or col in seen or box in seen:
                         return False
                     seen.add(row)
                     seen.add(col)
                     seen.add(box)
                     
         return True
         # for row in board:
         #     seen = 0
         #     for col in row:
         #         if col.isdigit():
         #             if seen >> int(col) & 1:
         #                 return False
         #             else:
         #                 seen |= 1<<int(col)
         # max = 9
         # for col in range(max):
         #     seen = 0
         #     for row in range(max):
         #         val = board[row][col]
         #         if val.isdigit():
         #             if seen >> int(val) & 1:
         #                 return False
         #             else:
         #                 seen |= 1<<int(val)
         # for row_st in range(0, max, 3):
         #     for col_st in range(0, max, 3):
         #         seen = 0
         #         for row in range(3):
         #             for col in range(3):
         #                 val = board[row_st + row][col_st+ col]
         #                 print(val)
         #                 if val.isdigit():
         #                     if seen >> int(val) & 1:
         #                         return False
         #                     else:
         #                         seen |= 1<<int(val)


class Solution:
     def isValidSudoku(self, board):
         """
         :type board: List[List[str]]
         :rtype: bool
         """
         anslist = sum(([(i,c),(c,j),(i//3,j//3,c)] for i,row in enumerate(board) for j,c in enumerate(row) if c != '.'),[])
         return len(anslist) == len(set(anslist))

class Solution:
     def isValidSudoku(self, board):
         """
         :type board: List[List[str]]
         :rtype: bool
         """
         Cell = [[] for i in range(9)]
         Col =  [[] for i in range(9)]
         Row =  [[] for i in range(9)]
         
         for i,row in enumerate(board):
             for j,num in enumerate(row):
                 if num != '.':
                     k = (i//3)*3 + j//3
                     if num in Row[i] + Col[j] + Cell[k]:
                         return False
                     Row[i].append(num)
                     Col[j].append(num)
                     Cell[k].append(num)
                         
         return True

class Solution:
     def isValidSudoku(self, board):
         """
         :type board: List[List[str]]
         :rtype: bool
         """
         rows = [[] for _ in range(9)]
         cols = [[] for _ in range(9)]
         areas = [[] for _ in range(9)]
         for i in range(9):
             for j in range(9):
                 ele = board[i][j]
                 if ele == '.':
                     continue
                 area_id = i // 3 * 3 + j // 3
                 if ele in rows[i] or ele in cols[j] or ele in areas[area_id]:
                     return False
                 else:
                     rows[i].append(ele)
                     cols[j].append(ele)
                     areas[area_id].append(ele)
         return True

class Solution:
     def isValidSudoku(self, board):
         """
         :type board: List[List[str]]
         :rtype: bool
         """
         check = set()
         for i in range(0, 9):
             for j in range(0, 9):
                 if (board[i][j] == '.'):
                     continue
                 if (board[i][j] in check):
                     return False
                 check.add(board[i][j])
             check.clear()
         
         for j in range(0,9):
             for i in range(0,9):
                 if (board[i][j] == "."):
                     continue
                 if (board[i][j] in check):
                     return False
                 check.add(board[i][j])
             check.clear()
             
         for k in range(0, 9):
             for i in range(int(k / 3) * 3, int(k / 3) * 3 + 3):
                 for j in range((k % 3) * 3, (k % 3) * 3 + 3):
                     if (board[i][j] == '.'):
                         continue
                     if (board[i][j] in check):
                         return False
                     check.add(board[i][j])
             check.clear()
     
         return True

class Solution:
     def isValidSudoku(self, board):
         """
         :type board: List[List[str]]
         :rtype: bool
         """
         if not board:return False
         checkRow=[[0 for i in range(9)]for j in range(9)]
         checkCol=[[0 for i in range(9)]for j in range(9)]
         checkSq=[[0 for i in range(9)] for j in range(9)]
         for i in range(9):
             for j in range(9):
                 k=i//3*3+j//3
                 if board[i][j]!='.':
                     num=int(board[i][j])-int('0')-1#from 1-9 to 0-8
                     if checkRow[i][num] or checkCol[j][num] or checkSq[k][num]:return False
                     else:checkRow[i][num]=checkCol[j][num]=checkSq[k][num]=1
         return True

class Solution:
     def isValidSudoku(self, board):
         """
         :type board: List[List[str]]
         :rtype: bool
         """
         for i in range (9):
             for j in range (9):
                 if board[i][j] == '.':
                     continue
                 temp = board[i][j]
                 board[i][j] = 'D'
                 if self.isValid(board, i, j, temp) == False:
                     return False
                 board[i][j] = temp
         return True
         
         
     def isValid(self, board, x, y, temp):
         for i in range (9):
             if board[i][y] == temp:
                 return False
         for i in range (9):
             if board[x][i] == temp:
                 return False
         for i in range (3):
             for j in range (3):
                 if board[x//3*3 + i][y//3*3 + j] == temp:
                     return False
         return True


class Solution:
     def isValidSudoku(self, board):
         """
         :type board: List[List[str]]
         :rtype: bool
         """
         for row in board:
             seen = 0
             for col in row:
                 if col.isdigit():
                     if seen >> int(col) & 1:
                         return False
                     else:
                         seen |= 1<<int(col)
         max = 9
         for col in range(max):
             seen = 0
             for row in range(max):
                 val = board[row][col]
                 if val.isdigit():
                     if seen >> int(val) & 1:
                         return False
                     else:
                         seen |= 1<<int(val)
         for row_st in range(0, max, 3):
             for col_st in range(0, max, 3):
                 seen = 0
                 for row in range(3):
                     for col in range(3):
                         val = board[row_st + row][col_st+ col]
                         print(val)
                         if val.isdigit():
                             if seen >> int(val) & 1:
                                 return False
                             else:
                                 seen |= 1<<int(val)
         
         return True

class Solution:
     def isValidSudoku(self, board):
         """
         :type board: List[List[str]]
         :rtype: bool
         """
         rows = []
         cols = []
         squares = []
         for i in range(0, len(board)):
             rows.append(set())
             cols.append(set())
             squares.append(set())
         for i in range(0, len(board)):
             for j in range(0, len(board)):
                 if board[i][j] == '.':
                     continue
                 val = board[i][j]
                 if val in rows[i]:
                     return False
                 rows[i].add(val)
                 if val in cols[j]:
                     return False
                 cols[j].add(val)
                 sq = int(i // 3) * 3
                 sq += int(j // 3)
                 print(('row is: ', i, ' col is: ', j, ' sq is: ', sq))
                 if val in squares[sq]:
                     return False
                 squares[sq].add(val)
         return True


class Solution:
     def isValidSudoku(self, board):
         """
         :type board: List[List[str]]
         :rtype: bool
         """
         seen = sum(([(c, i), (j, c), (i//3, j//3, c)]
                 for i, row in enumerate(board)
                 for j, c in enumerate(row)
                 if c != '.'), [])
         print(seen)
         return len(seen) == len(set(seen))


class Solution:
     def isValidSudoku(self, board):
         """
         :type board: List[List[str]]
         :rtype: bool
         """
         for l in board:
             nums = list(collections.Counter(l).items())
             for term in nums:
                 if term[0] != '.' and term[1] > 1:
                     print(1)
                     return False
 
         for i in range(0, len(board), 3):
             rows = list(zip(*board[i: i + 3]))
             for j in range(0, len(board), 3):
                 nums = list(itertools.chain.from_iterable(rows[j: j + 3]))
                 nums = list(collections.Counter(nums).items())
                 for term in nums:
                     if term[0] != '.' and term[1] > 1:
                         print(3)
                         return False
 
         columns = list(zip(*board))
         for l in columns:
             nums = list(collections.Counter(l).items())
             for term in nums:
                 if term[0] != '.' and term[1] > 1:
                     print(2)
                     return False
 
         return True