Question

So I am writing a sudoku solver using a 9x9 array for the grid and a 9x9x9 array for its possibilities. Due to the backtracking algorithm I am using, I have to check whether the Sudoku is still valid, aka:

If there is a field that does not contain a number and has no possibilities left, return False. So far I implemented that as follows:

    for j in range(9):
        for i in range(9):
            if puzzle[j,i] == 0 and (solving[j,i] == 0).sum() == 9:
                return False
    return True

If the square at (j,i) contained, for example, the options 2, 3 and 7, the according possibility array would be:

    solving[j,i] = array([0, 2, 3, 0, 0, 0, 7, 0, 0], dtype = int8)

I am trying to avoid such loops here and elsewhere in my solver. I tried this as follows:

    solving[where(puzzle == 0)]

This returned an n x 9 array, where n is the amount of empty squares in my puzzle. I want the function to return False if any of the n arrays with shape 1x9 is exactly equal to

    array([0,0,0,0,0,0,0,0,0], dtype = int8)

However, I did not have any success with various tries including .any() and .all() experiments. This is the latest code I was using:

    def is_valid(self, puzzle, solving):
        if (solving[py.where(puzzle == 0)].all() == 0).sum() > 0:
            return False
        return True

... which always returns False. What's the proper way to code this?

Was it helpful?

Solution

I think the following is the check you want to do:

np.all(puzzle | np.any(solving, axis=-1)

This returns True if all cells either have a value assigned (puzzle), or (|) have at least a non-zero entry in solving (np.any(solving, axis=-1)).

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top