Does any body have an idea why my valid, or doubles methods don't want to work? First I make a new 9x9 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
CodePudding user response:
There are three issues in the code you have written:
make_sudoku
only creates one row, and adds that same row 9 times tosudoku
. 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 returnsTrue
. This is because the value at indexe
will of course be found inrow
-- 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 fromrow
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 thatand
should be anor
. 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