pythonsudoku

Sudoku block checker in python


This kind of question has been asked before but I came up with a solution I do not see very often. Now this works on my local host but when I input it into the University program it returns that I've failed the funcitonality check but I pass it on my local host. I need to check a 3 by 3 block with a row and column entry. I get false when I should get false.

    sudoku = [
      [9, 0, 0, 0, 8, 0, 3, 0, 0],
      [2, 0, 0, 2, 5, 0, 7, 0, 0],
      [0, 2, 0, 3, 0, 0, 0, 0, 4],
      [2, 9, 4, 0, 0, 0, 0, 0, 0],
      [0, 0, 0, 7, 3, 0, 5, 6, 0],
      [7, 0, 5, 0, 6, 0, 4, 0, 0],
      [0, 0, 7, 8, 0, 3, 9, 0, 0],
      [0, 0, 1, 0, 0, 0, 0, 0, 3],
      [3, 0, 0, 0, 0, 0, 0, 0, 2]
    ]


    def block_correct(sudoku: list, row_no: int, column_no:int):

        correct = [1,2,3,4,5,6,7,8,9]       # this is the list I compare to

        n=0                                 #counter for rows
        b=0                                 #counter for columns
        check_sq= []                        #list i use to compare to correct sudoku list
        col_noin = column_no                #required to remember 3x3 block
        while True:                         #loop for columns
            if b==3:
                break 
    
            while True:                     #loop for rows
                if n==3:
                    break        
                check_sq.append(sudoku[row_no][column_no])     #this adds entries into checking list

                column_no += 1
                n+=1
            b += 1
            row_no += 1
            column_no = col_noin 
            n=0



        if bool(set(correct).difference(check_sq)) == False:    #this determines if loops are the same
            return True
        else:
            return False

    print(block_correct(sudoku,2,2))

Solution

  • I think the issue is your while True loops with if b == 3: break and if n == 3: break don't accurately confine the traversal to a valid 3x3 Sudoku block. Your code might go out of bounds of the grid or not cover the entire block but cover an irrelevant 3x3 block across multiple valid 3x3 blocks.

    Try adding logic to ensure the start_row and start_col is valid, your current code could result in an IndexError or an incorrect result if some row_no or column_no is provided that is not exactly the top left cell of a valid 3x3 block:

    def block_correct(sudoku: list[list[int]], row_no: int, column_no: int) -> bool:
      correct = [1, 2, 3, 4, 5, 6, 7, 8, 9]
      check_sq = []
      start_row = row_no // 3 * 3 
      start_col = column_no // 3 * 3
      for r in range(start_row, start_row + 3):
        for c in range(start_col, start_col + 3):
          check_sq.append(sudoku[r][c])
      return not set(correct).difference(check_sq)
    
    sudoku = [
      [9, 7, 8, 0, 8, 0, 3, 0, 0],
      [4, 5, 6, 2, 5, 0, 7, 0, 0],
      [1, 2, 3, 3, 0, 0, 0, 0, 4],
      [2, 9, 4, 0, 0, 0, 0, 0, 0],
      [0, 0, 0, 7, 3, 0, 5, 6, 0],
      [7, 0, 5, 0, 6, 0, 4, 0, 0],
      [0, 0, 7, 8, 0, 3, 9, 0, 0],
      [0, 0, 1, 0, 0, 0, 0, 0, 3],
      [3, 0, 0, 0, 0, 0, 0, 0, 2],
    ]
    print(block_correct(sudoku, 0, 0))  # True
    print(block_correct(sudoku, 8, 8))  # False but would throw an IndexError with your current code