I wanted to make a sudoku an check if it is a valid one

Question:

Does any body have an idea why my valid, or doubles methods don’t want to work?
First I make a new 9×9 sudoku with al positions None. afterwards with the method doubles i check whether there are any duplicates in a row, if so I return True. A last if check with the method valid if the row and columns are valid, if so I return true. The print_sudoku method is just to print out the sudoku nicely.

def make_sudoku():
   sudoku = []
   row = [None, None, None, None, None, None, None, None, None]
   for i in range(9):
       sudoku.append(row)
   return sudoku


def doubles(row):
    for e in range(len(row)):
        if row[e] in row:
            return True
    return False


def valid(sudoku):
    for i in range(9):
        column = []
        for j in range(9):
            column.append(sudoku[j][i])
        row = sudoku[i]
        if (doubles(row) and doubles(column)):
            return False

   # TODO in: Check Code every 9 blocks on duplicates

   return True




def print_sudoku(s):
    """
        Help functie om een sudoku mooi uit te printen
    """
    print("+-----------------+-----------------+-----------------+")
    for x in range(9):
        print("|", end="")
        for y in range(9):
            if s[x][y] is not None:
                print(" ", s[x][y], " ", end="")
            else:
                print("  _  ", end="")
            if ((y+1)%3) != 0:
                print(" ", end="")
            else:
                print("|", end="")
        print()
        if ((x+1)%3 == 0):
            print("+-----------------+-----------------+-----------------+")
        else:
            print("|                 |                 |                 |")


if __name__ == "__main__":
    # Begin debugging
    s1 = make_sudoku()
    print_sudoku(s1)

    s1[0][0] = 5
    s1[1][2] = 3
    s1[7][7] = 2
    s1[8][8] = 4

    print_sudoku(s1)

    print(valid(s1))
    s1[0][1] = 5
    print(valid(s1))

Output:

+-----------------+-----------------+-----------------+
|  _     _     _  |  _     _     _  |  _     _     _  |
|                 |                 |                 |
|  _     _     _  |  _     _     _  |  _     _     _  |
|                 |                 |                 |
|  _     _     _  |  _     _     _  |  _     _     _  |
+-----------------+-----------------+-----------------+
|  _     _     _  |  _     _     _  |  _     _     _  |
|                 |                 |                 |
|  _     _     _  |  _     _     _  |  _     _     _  |
|                 |                 |                 |
|  _     _     _  |  _     _     _  |  _     _     _  |
+-----------------+-----------------+-----------------+
|  _     _     _  |  _     _     _  |  _     _     _  |
|                 |                 |                 |
|  _     _     _  |  _     _     _  |  _     _     _  |
|                 |                 |                 |
|  _     _     _  |  _     _     _  |  _     _     _  |
+-----------------+-----------------+-----------------+
+-----------------+-----------------+-----------------+
|  5     _     3  |  _     _     _  |  _     2     4  |
|                 |                 |                 |
|  5     _     3  |  _     _     _  |  _     2     4  |
|                 |                 |                 |
|  5     _     3  |  _     _     _  |  _     2     4  |
+-----------------+-----------------+-----------------+
|  5     _     3  |  _     _     _  |  _     2     4  |
|                 |                 |                 |
|  5     _     3  |  _     _     _  |  _     2     4  |
|                 |                 |                 |
|  5     _     3  |  _     _     _  |  _     2     4  |
+-----------------+-----------------+-----------------+
|  5     _     3  |  _     _     _  |  _     2     4  |
|                 |                 |                 |
|  5     _     3  |  _     _     _  |  _     2     4  |
|                 |                 |                 |
|  5     _     3  |  _     _     _  |  _     2     4  |
+-----------------+-----------------+-----------------+
False
False

My wish to output would be:

The first sudoku + the second sudoku but than a valid one
True
False

Thanks in advance <3

Asked By: SiBMs

||

Answers:

There are three issues in the code you have written:

  • make_sudoku only creates one row, and adds that same row 9 times to sudoku. That means you have 9 references to the same row. That’s not what you want. You want 9 separate rows. So in each iteration of the loop a new row must be created. You can for instance slice the "template" row that was created before the loop.

  • doubles always returns True. This is because the value at index e will of course be found in row — you just retrieved it from there! Secondly, None is allowed to appear more than once in the same row, so that value should be ignored when making a duplicate check. What you can do is keep track for all digits (1..9) whether you have already encountered it before or not. Each time you retrieve a digit from row check whether you have already encountered it. If not, mark it as such.

  • In valid you should not check that there is a duplicate in a row and there is a duplicate in a column (at the same time), but that either condition is true. So that and should be an or. It is boolean logic.

Here is your code with those three corrections (marked with a comment):

def make_sudoku():
   sudoku = []
   row = [None, None, None, None, None, None, None, None, None]
   for i in range(9):
       sudoku.append(row[:])  # Create a new row each time!
   return sudoku


def doubles(row):  # Completely rewritten
    collected = [False] * 10
    for val in row:
        if val is not None:  # `None` is never a problem!
            if collected[val]:  # If this digit already occurred before...
                return True
            collected[val] = True  # Mark this digit as having occurred once
    return False


def valid(sudoku):
    for i in range(9):
        column = []
        for j in range(9):
            column.append(sudoku[j][i])
        row = sudoku[i]
        if doubles(row) or doubles(column):  # One True is enough to have a problem
            return False
Answered By: trincot
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.