0

Possible Duplicate:
Sudoku backtracking algorithm

I have no idea why I can't think straight right now but as of right now, but I was hoping for some help in developing an algorithm for my sudoku puzzle. I have a a list of possible numbers that can go in each cell after checking all the rows, columns, and 3x3's. I have code for placing numbers into each cell. However, I'm having a lot of trouble with the backtrakcing aspect. Can anyone help me with some psuedocode for the backtracking part of the sudoku puzzle?

Thanks.

Community
  • 1
  • 1
user1567909
  • 1,450
  • 2
  • 14
  • 24

2 Answers2

0

Something like this?

solve_suduko(Puzzle& p)
{
  for (m : all possible moves)
  { 
     p.make_move(m);
     if (p.solved())
     {
       print_solution(p);
     }
     else if (p.partial_solution())
     {
       solve_suduko(p);
     }
     p.unmake_move(m);
  }
}

I guess you may not need partial_solution if your move generation code always generates moves that lead to partial solutions. I think that would be the case for suduko.

john
  • 85,011
  • 4
  • 57
  • 81
  • Yeah, do you mind sharing the unmake_move(m) psuedo code for me? I'd really apreciate it – user1567909 Oct 18 '12 at 20:48
  • I have no pseudo code for unmake_move. It's fairly easy though isn't it, you just have to remember the previous value of the square, i.e. `int prev = p.get_value(m); p.make_move(m); ... p.unmake_move(m, prev);` – john Oct 18 '12 at 20:56
0

You could try a stack-based approached. Either using the call stack via recursion, where the backtracking is returning false up the stack:

def solveBoard(partialBoard):
    nextUnsolvedBlock = getNextBlock(partialBoard)
    possibles = generatePossiblePositions(partialBoard)
    for possibility in possibles:
        result = solveBoard(partialBoard)
        if result.valid:
            return result;

This approach is limited largely by the size of the stack; it is not tail-recusive, so the stack must grow, and its maximum size is the number of steps from empty board to complete board.

The alternative is to construct your own stack, which will permit many more such steps because it will be stored on the heap:

def solveBoard(partialBoard):
    stack = [(partialBoard,0,0)] // (board, nextBlock, blockOptionIndex)
    while stack.last[0].valid == false:
        nextBlockOption = getNextBlockOption(stack.last)
        if nextBlockOption == None:
            pop(stack)
            nextBlock = getNextBlock(stack.last)
            if nextBlock = None:
                exit("No solution")
            else:
                stack.last[2] = nextBlock
        else:
            stack.last[1] = nextBlockOption
    return stack.last[0]

For bonus points, redo the stack approach using a generator say generateBoards, which starts with a given board and keeps generating new boards in a consistent pattern. That way your algo would be just:

def solveBoard(initialBoard):
    for board in generateBoards(initialBoard):
        if isValid(board):
            return board
    return "No solution found"

And the complexity is then really in generateBoards:

def generateBoards(partialBoard):
    nextUnsolvedBlock = getNextBlock(partialBoard)
    for possibility in generatePossiblePositions(partialBoard):
        yield possibility

If you write generatePossiblePositions also as a generator, then these two can work together until the thing is done. Because this uses generators rather than recursion, the stack does not grow, and the new boards are generated as you need them rather than all in advance, so the storage requirements are also low. Rather elegant, really, with the power of generators.

Phil H
  • 19,928
  • 7
  • 68
  • 105