pythonsudoku

Python sudoku checker


I'm working on an assignment for my CIS class in python. We have to code a Sudoku checker. In a 9x9 board we obviously have to check each row, col and 3x3 square for duplicates. I'm a little stuck on the idea of how to check the numbers by a 3x3 square. Below is my code for checking each row and col, if someone could help me a little with an outline or an approach just something for checking each 3x3 square that would be amazing!

self.columns = [ ]
     for col in range(9):
        col_tiles = [ ]
        self.columns.append(col_tiles)
        for row in range(9):
            col_tiles.append(self.tiles[row][col])
self.squares = [ ]
for col in range(1, 10, 3):
        for row in range(1, 10, 3):
            square_tiles = [ ]
            self.squares.append(square_tiles)
            for x in range(3):
                for y in range(3):
                    square_tiles.append(self.tiles[x][y])

Solution

  • This assumes you have the freedom to read the data and structure how you want. We want a set of unique values 1-9 for each row/column/3x3 grid, so one way is to either use a set or a list comparison (we'll use set here to make it cleaner). If we create a set equal to the numbers from 1 to 9, we have a point against which we can compare all of our other groups. Assume a structure like this (from here):

    In [1]: r1 = [9,3,2,5,4,8,1,7,6]
    
    In [2]: r2 = [1,8,7,9,2,6,5,4,3]
    
    In [3]: r3 = [5,4,6,3,7,1,2,8,9]
    
    # Continues....
    

    Where each row represents a full row of data. Now lets create a section of that data that represents the first three rows, pull out one grid and compare the contents to our set:

    In [4]: sec1 = [r1, r2, r3]
    
    In [5]: nums = set(range(1, 10))
    
    In [6]: nums == set(n for row in sec1 for n in row[:3])
    Out[6]: True
    

    This iterates over the first three rows and returns the first three elements in each of those rows. To get a better visual, here is the equivalent for-loop code to make it a bit easier to decipher:

    result = set()
    for row in sec1:
        for n in row[:3]:
          result.add(n)
    

    Since our set of numbers includes everything from 1-9, we know it is valid. To move to the second, we range the row[:3] to row[3:6] (and row[6:9] after that). You'll then need to handle this for the next two sections as well. I'll leave it to you as to how to wrap this in a more dynamic structure (note the multiples of three), but hopefully this will get you started :)