def recurse(self, heap, constraints): """ Dfs and backtrack for solution. for item in heap: for choice in item constraints: copy constraints, remove choice, recurse self.board does not reflect current recursion state of board (constraints do) but will have final solution when constraints are empty """ while heap: item = heapq.heappop(heap) coords = item.coords choices = list(constraints.row[coords.row] & constraints.col[coords.col] & constraints.square[coords.square]) if not choices: return False for num in choices: self.board[item.coords.row][item.coords.col] = num cc = Constraints.copy(constraints) cc.row[coords.row].remove(num) cc.col[coords.col].remove(num) cc.square[coords.square].remove(num) result = self.recurse(deepcopy(heap), cc) # recurse with new constraints if result: return True return False
def recurse(self, coords, constraints): """ Dfs and backtrack for solution. for choice in constraints: copy constraints, remove choice, recurse self.board does not reflect current recursion state of board (constraints do) but will have final solution when constraints are empty """ if coords.row == self.n and coords.col == 0: return True choices = list( constraints.row[coords.row] & constraints.col[coords.col] & constraints.square[coords.square]) if not choices: # backtrack return False while choices: num_assigned = choices.pop() self.board[coords.row][coords.col] = num_assigned cc = Constraints.copy(constraints) cc.row[coords.row].remove(num_assigned) cc.col[coords.col].remove(num_assigned) cc.square[coords.square].remove(num_assigned) next_coords = self.next_cell_coords(coords) result = self.recurse(next_coords, cc) if result: return True return False