Untitled
def create_possibilities(grid): """Create a dictionary of possible values for each cell.""" possibilities = {} for row in range(9): for col in range(9): if grid[row][col] == 0: possibilities[(row, col)] = set(range(1, 10)) # All numbers are possible initially else: possibilities[(row, col)] = {grid[row][col]} # Already filled cell return possibilities def eliminate(possibilities, grid): """Eliminate impossible numbers from possibilities.""" for row in range(9): for col in range(9): if len(possibilities[(row, col)]) == 1: # If only one value, eliminate it from peers number = next(iter(possibilities[(row, col)])) # Eliminate from row, column, and 3x3 subgrid for i in range(9): if (row, i) != (row, col): possibilities[(row, i)].discard(number) # Row if (i, col) != (row, col): possibilities[(i, col)].discard(number) # Column r, c = (row // 3) * 3, (col // 3) * 3 for i in range(3): for j in range(3): if (r + i, c + j) != (row, col): possibilities[(r + i, c + j)].discard(number) # Subgrid def solve_with_constraints(grid): """Solve Sudoku using Constraint Propagation.""" possibilities = create_possibilities(grid) while True: prev_state = {k: set(v) for k, v in possibilities.items()} # Copy current state eliminate(possibilities, grid) # If no progress is made, break if all(prev_state[k] == possibilities[k] for k in possibilities): break # Fill the grid with determined values for row in range(9): for col in range(9): if len(possibilities[(row, col)]) == 1: grid[row][col] = next(iter(possibilities[(row, col)])) # If some cells still have multiple possibilities, return False if any(len(v) > 1 for v in possibilities.values()): return False return True
Leave a Comment