0

I am trying to make a function that will keep trying different numbers in a cell of a board made with a 2D list until its constraints are met. However, for some reason when I output the row and column that is being tested, it works normally until it suddenly goes back an entire row with a column index out of range.

def sudoku_solver(row=None, col=None):
    if row is None:
        row = 0

    if col is None:
        col = 0

    global board
    if col >= len(board) - 1:
        sudoku_solver(row=row + 1)

    if row >= len(board) - 1:
        display_board()
        exit()

    print(row, col)
    for n in range(1, 10):
        if valid(n, row, col):
            board[row][col] = n
            sudoku_solver(row, col=col + 1)
        elif board[row][col] != 0:
            sudoku_solver(row, col=col + 1)
        else:
            pass # board[row][col] = 0

    return False

Output:

....(a lot of tests)

5 3

5 4

5 4

5 4

5 4

5 4

5 4

4 9

This is the board:

 board = [
    [0, 0, 0, 2, 6, 0, 7, 0, 1],
    [6, 8, 0, 0, 7, 0, 0, 9, 0],
    [1, 9, 0, 0, 0, 4, 5, 0, 0],
    [8, 2, 0, 1, 0, 0, 0, 4, 0],
    [0, 0, 4, 6, 0, 2, 9, 0, 0],
    [0, 5, 0, 0, 0, 3, 0, 2, 8],
    [0, 0, 9, 3, 0, 0, 0, 7, 4],
    [0, 4, 0, 0, 5, 0, 0, 3, 6],
    [7, 0, 3, 0, 1, 8, 0, 0, 0]
]
Alan Shiah
  • 907
  • 1
  • 6
  • 19
  • 1
    When you call a function, the passed-in values are **not copied**. Therefore, every recursive call refers to the **same nested list object**, and changes are reflected both "forwards" and "backwards" in the recursion. It is very difficult to write correct recursive code using mutable data structures like this. (it is also a **very bad idea** to use things like `exit` within a recursive function. This takes control of the program flow away from the caller.) – Karl Knechtel May 06 '22 at 03:54
  • I don't quite understand why that would cause my row and col to change from 5 4 to 4 9. Could you elaborate? – Alan Shiah May 06 '22 at 03:59
  • 1
    Ah, you are asking a question that is unrelated to the problem I highlighted. Each recursive call has its own set of local variables, and whenever a recursive call completes, execution returns to where it was called from - *just like* as if it were called *by any other function*. In that calling context, since it has its own set of local variables, the values are whatever they were immediately before the recursive call - *just like* they would be *in any other case* of calling a function. – Karl Knechtel May 06 '22 at 04:05
  • 1
    Functions do not have local variables themselves; a **call to** a function has local variables. Since the function is called multiple times (potentially with many of those calls 'suspended' waiting for another to complete), there are multiple separate sets of local variables (these sets are sometimes called "stack frames" or "call frames"). – Karl Knechtel May 06 '22 at 04:06
  • Ah, so what you're saying is that because I have multiple of these 'suspended' calls waiting for another to complete, I have multiple sets of local variables. And because I have multiple sets of local variables, does it cause a glitch of some sort? I get what you are saying but does that mean the output 4 9 is a glitch? If its organized in a call stack, shouldn't the next row and col printed be based off the local variables of the last call? – Alan Shiah May 06 '22 at 04:18
  • 1
    It does not "cause a glitch". It is supposed to work that way. You are supposed to write an algorithm that takes advantage of that. Please try to look up a tutorial on recursion to gain a better understanding. This is *not a discussion forum* and it is not feasible to explain the topic properly in this format. – Karl Knechtel May 06 '22 at 04:20
  • 1
    (As a hint, though: you know how it's called "recursive backtracking"? Do you see how this reversion to the prior set of local variables, when the recursive call returns, represents a kind of back-tracking?) – Karl Knechtel May 06 '22 at 04:21
  • Oh my goodness, thank you so much. I just put it all together. I understand how the algorithm works, and I watched tutorials on recursive backtracking. Though I was misinterpreting how a recursive call works. Your explanation of call stacks just made me realize why it actually is backtracking and how I should solve it. Thanks. – Alan Shiah May 06 '22 at 04:26

0 Answers0