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_sudokuonly 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.doublesalways returnsTrue. This is because the value at indexewill of course be found inrow-- you just retrieved it from there! Secondly,Noneis 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 fromrowcheck whether you have already encountered it. If not, mark it as such.In
validyou 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 thatandshould 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
