Welcome to WuJiGu Developer Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
394 views
in Technique[技术] by (71.8m points)

python - I have a sudoku solver that works, but I don't know why! Specifically the recursion loop, I don't know how I got it to work

I'll post the code below, but a brief first. The solver takes an array, finds an empty square represented by a 0, and checks to see if any number 1-9 fits. If so, it replaces it, and moves onto the next square. For days it just would fill out half the board, but after some tinkering I got it to magically work, but I really don't know how. You'll see that below the two functions, next_empty_square and is_valid, I have the main loop that performs the operation, which is this:

for n in range(1, 10): ## here is our main loop 

        if is_valid(y, x, n, board): 
            board[y][x] = n
            if sudoku_solver(board): 
                return board

        board[y][x] = 0

This main loop is where I am confused. I don't know why "if sudoku_solver(board):" suddenly makes it backtrack(it didn't before I worded it specifically this way), and why "board[y][x] =0" doesn't just reset the same square over and over. I am pretty new to this and am learning on my own, so any help would be very much appreciated. Working with grids and lists and arrays is one thing but this recursion stuff really makes my brain hurt.

testboard = [
    [7,8,0,4,0,0,1,2,0],
    [6,0,0,0,7,5,0,0,9],
    [0,0,0,6,0,1,0,7,8],
    [0,0,7,0,4,0,2,6,0],
    [0,0,1,0,5,0,9,3,0],
    [9,0,4,0,6,0,0,0,5],
    [0,7,0,3,0,0,0,1,2],
    [1,2,0,0,0,7,4,0,0],
    [0,4,9,2,0,6,0,0,7]
]


def sudoku_solver(board): 

    def next_empty_square(board):
        """Takes a sudoku board and returns the first empty square in the form of a row(y), column(x) coordinate""" 
        for y in range(9): 
            for x in range(9): 
                if board[y][x] == 0: 
                    return y, x
    

    if next_empty_square(board) is None:                   #if the board is full, it will return none. In that case, return true. 
        return True

        
    y, x = next_empty_square(board)            #gives us the coordinates for the next empty square to use for the is_valid function

    def is_valid(y, x, n, board):
        """Takes a y coordinate, an x coordinate, a number(n), and our sudoku board. It checks to see if the number fits in 
        the coordinates of our board by checking the row, column and 3x3 grid in which the coordinate occurs for other instances of that number.""" 
        
        for i in range(9):             #This loop checks the row 
            if board[y][i] == n: 
                return False
        
        for i in range(9):             #this loop checks the column
            if board[i][x]== n: 
                return False

        ygrid = (y//3)*3
        xgrid = (x//3)*3

        for i in range(0,3):           #This loop checks the 3x3 grid 
            for j in range(0,3): 
                if board[ygrid+i][xgrid+j]==n:
                    return False  

        return True

    for n in range(1, 10):                    ## here is our main loop 

        if is_valid(y, x, n, board): 
            board[y][x] = n
            if sudoku_solver(board):                 ## this is where I have a problem. I am not sure why this recursive function works! Why does it backtrack?
                return board

        board[y][x] = 0                       # I am also not sure why this resets the square that it needs to. It seems like it would just reset the same square over and over 
    return False


    


def sudoku_printer(board): 
    """Takes our array and prints it to look like a sudoku board"""                         
    for i in range(len(board)): 
        if i%3 == 0: 
            print("- - - - - - - - - - - -")

        for j in range(len(board[0])):
            if j %3 == 0: 
                print( "| ", end ="")
            if j == 8: 
                print(str(board[i][j])+ " |")

            else: 
                print(str(board[i][j]) + " ", end ="")
    print("- - - - - - - - - - - -")

sudoku_printer(sudoku_solver(testboard))

    

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)
等待大神答复

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to WuJiGu Developer Q&A Community for programmer and developer-Open, Learning and Share

2.1m questions

2.1m answers

62 comments

56.7k users

...