Search code examples
pythonpython-3.xalgorithmbacktracking

How to add another condition to Sudoku puzzle


I have just start coding with python since fall. So i am not a professional python coder. I have started to code a Sudoku program. And fortunately at last I could have come up with this code:

def isValid(num, x, y):
    for i in range(9):
        if board[i][y] == num:
            return False
        if board[x][i] == num:
            return False
    row = x - x % 3
    col = y - y % 3
    for i in range(3):
        for j in range(3):
            if board[i + row][j + col] == num:
                return False
    return True
def solve(remaining):
    if remaining == 0:
        return True
    for i in range(9):
        for j in range(9):
            if board[i][j] != 0:
                continue
            for num in range(1, 10):
                if isValid(num, i, j):
                    board[i][j] = num
                    if solve(remaining - 1):
                        return True
                    board[i][j] = 0
            return False
    return False
def pp():
    for i in range(9):
        for j in range(9):
            print(board[i][j], end=" ")
        print()
    print()
board = []
remaining = 0
for i in range(9):
    a=input()
    a=a.split()
    a = list(map(int, a))
    for j in a:
        if j == 0:
            remaining += 1
    board.append(a)
solve(remaining)
pp()

For instance I give such an input to it:

0 0 0 0 0 0 0 1 0
0 0 2 0 0 0 0 3 4
0 0 0 0 5 1 0 0 0
0 0 0 0 0 6 5 0 0
0 7 0 3 0 0 0 8 0
0 0 3 0 0 0 0 0 0
0 0 0 0 8 0 0 0 0
5 8 0 0 0 0 9 0 0
6 9 0 0 0 0 0 0 0

And this is my output:

7 4 9 2 3 8 6 1 5 
1 5 2 6 9 7 8 3 4 
8 3 6 4 5 1 2 7 9 
2 1 8 9 7 6 5 4 3 
9 7 5 3 2 4 1 8 6 
4 6 3 8 1 5 7 9 2 
3 2 1 5 8 9 4 6 7 
5 8 4 7 6 3 9 2 1 
6 9 7 1 4 2 3 5 8 

Now I intend to add a new condition to this Sudoku which is can do this process for 4 more 3*3 boxes in the board like this (which is named Hyper-Sudoku):

That for my puzzle it returns:

9 4 6 8 3 2 7 1 5
1 5 2 6 9 7 8 3 4
7 3 8 4 5 1 2 9 6
8 1 9 7 2 6 5 4 3
4 7 5 3 1 9 6 8 2
2 6 3 5 4 8 1 7 9
3 2 7 9 8 5 4 6 1
5 8 4 1 6 3 9 2 7
6 9 1 2 7 4 3 5 8

Is there any way to add this option to my Sudoku or not, I have to change my whole algorithm?

Thanks for your answers.


Solution

  • I think your program looks great. Since you separated your isValid and solve functions it makes adding the change easier. All you will need to is modify the isValid function.

    def isValid(num, x, y):
        # row and column check
        for i in range(9):
            if board[i][y] == num:
                return False
            if board[x][i] == num:
                return False
    
        # 3x3 tile check
        row = x - x % 3
        col = y - y % 3
        for i in range(3):
            for j in range(3):
                if board[i + row][j + col] == num:
                    return False
    
        # Hypersudoku check
        if x not in [0, 4, 8] and y not in [0, 4, 8]:
            row = 1 if x < 4 else 5
            col = 1 if y < 4 else 5
            for i in range(3):
                for j in range(3):
                    if board[i + row][j + col] == num:
                         return False
    
        return True