def get_solution(unsolved_matrix, print_solution=False): if Validator.is_9x9_integers_field(unsolved_matrix): solution = SudokuSolver._solve_sudoku(unsolved_matrix) if solution: if print_solution: SudokuSolver.print_sudoku(unsolved_matrix) return unsolved_matrix if print_solution: print("No solution!") return False # can not solve sudoku raise InappropriateArgsError("getting solution for sudoku field")
def test_correct_is_9x9_integers_field(self): field = [ [1, 0, 2, 0, 0, 0, 5, 3, 4], [1, 0, 2, 0, 0, 0, 5, 3, 4], [1, 0, 2, 0, 0, 0, 5, 3, 4], [1, 0, 2, 0, 0, 0, 5, 3, 4], [1, 0, 2, 0, 0, 0, 5, 3, 4], [1, 0, 2, 0, 0, 0, 5, 3, 4], [1, 0, 2, 0, 0, 0, 5, 3, 4], [1, 0, 2, 0, 0, 0, 5, 3, 4], [1, 0, 2, 0, 0, 0, 5, 3, 4], ] self.assertEqual(Validator.is_9x9_integers_field(field), True)
def _number_unassigned(matrix): if Validator.is_9x9_integers_field(matrix): num_unassign = 0 for i in range(0, SIZE): for j in range(0, SIZE): if matrix[i][j] == 0: # cell is unassigned row = i col = j num_unassign = 1 a = [row, col, num_unassign] return a a = [-1, -1, num_unassign] return a raise InappropriateArgsError("number unassigned")
def __init__(self, field, loaded_from): if Validator.is_9x9_integers_field(field): super().__init__("Continue", self._go_to_solution, field, loaded_from) self.label_text = "If the numbers are matching press 'Continue',\n else manually change the wrong ones." self.set_info_label(self.label_text) show_image_frame = widgets.Frame(self.bot_frame, row=0, column=1, sticky="w") self.show_image_button = widgets.Button(show_image_frame, "Show field", self._show_detected_field) self.bind("<Return>", self._go_to_solution) # continue when user press enter self.focus_force() else: raise InappropriateArgsError( "creating error handling view (AskIfCorrectView)!")
def _is_safe(matrix, n, r, c): if Validator.is_9x9_integers_field(matrix) and \ Validator.is_positive_number([n, r, c]) and Validator.is_type([n, r, c], int): # positive integers # checking in row for i in range(0, SIZE): # there is a cell with same value if matrix[r][i] == n: return False # checking in column for i in range(0, SIZE): # there is a cell with same value if matrix[i][c] == n: return False row_start = (r // 3) * 3 col_start = (c // 3) * 3 # checking submatrix for i in range(row_start, row_start + 3): for j in range(col_start, col_start + 3): if matrix[i][j] == n: return False return True raise InappropriateArgsError("checking if sudoku is save")
def __init__(self, bt_text, bt_funct, field_numbers, loaded_from, readonly=False, detected=None): """ creates a template with Sudoku field. :param bt_text: text of the button :param bt_funct: function of the button :param field_numbers: numbers that are in the field... 2d array with 9 elements each """ if Validator.is_type(bt_text, str) and Validator.is_function(bt_funct) and \ Validator.is_type(readonly, bool) and Validator.is_9x9_integers_field(field_numbers): tkinter._default_root = self super().__init__("Go Back", self._go_back, bt_text, bt_funct) self.content_frame = widgets.Frame(self, row=2, padx=var.BORDER, pady=var.BORDER) self.field_numbers = field_numbers # 2d list of input digits self.readonly = readonly self.loaded_from = loaded_from self.detected = detected # non empty fields (from original field) if self.detected is None: self.detected = [] self.text_edits = self._generate_field() # 2d list of entries self._set_to_screen_center() else: raise InappropriateArgsError("creating a sudoku field template!")
def _solve_sudoku(unsolved_matrix): if Validator.is_9x9_integers_field(unsolved_matrix): # if all cells are assigned then the sudoku is already solved # pass by reference because number_unassigned will change the values of row and col a = SudokuSolver._number_unassigned(unsolved_matrix) if a[2] == 0: return True row = a[0] col = a[1] # number between 1 to 9 for i in range(1, SIZE + 1): # if we can assign i to the cell or not # the cell is matrix[row][col] if SudokuSolver._is_safe(unsolved_matrix, i, row, col): unsolved_matrix[row][col] = i # backtracking if SudokuSolver._solve_sudoku(unsolved_matrix): return True # if we can't proceed with this solution # reassign the cell unsolved_matrix[row][col] = 0 return False raise InappropriateArgsError("solving sudoku")
def test_incorrect_is_9x9_integers_field(self): field1 = [ [1, 0, 2, 0, 0, 0, 5, 3, 4], [1, 0, 2, 0, 0, 0, 5, 3, 4], [1, 0, 2, 0, 0, 0, 5, 3, 4], [1, 0, 2, 0, 0, 0, 5, 3], [1, 0, 2, 0, 0, 0, 5, 3, 4], [1, 0, 2, 0, 0, 0, 5, 3, 4], [1, 0, 2, 0, 0, 0, 5, 3, 4], [1, 0, 2, 0, 0, 0, 5, 3, 4], [1, 0, 2, 0, 0, 0, 5, 3, 4], ] field2 = [ [1, 0, 2, 0, 0, 0, 5, 3, 4], [1, 0, 2, 0, 0, 0, 5, 3, 4], [1, 0, 2, 0, 0, 0, 5, 3, 4], [1, 0, 2, 0, 0, 0, 5, 3, 4], [1, 0, 2, 0, 0, 0, 5, 3, 4], [1, 0, 2, 0, 0, 0, 5, 3, 4], [1, 0, 2, 0, 0, 0, 5, 3, 4], [1, 0, 2, 0, 0, 0, 5, 3, 4], ] field3 = [ [1, 0, 2, 0, 0, 0, 5, 3, 4], [1, 0, 2, 0, 0, 0, 5, 3, 4], [1, 0, 2, 0, 0, 0, 5, 3, 4], [1, 0, 2, 0, 0, 0, 5, 3, 4], [1, 0, 2, 0, 0, 0, 5, 3, 4], [1, 0, -2, 0, 0, 0, 5, 3, 4], [1, 0, 2, 0, 0, 0, 5, 3, 4], [1, 0, 2, 0, 0, 0, 5, 3, 4], [1, 0, 2, 0, 0, 0, 5, 3, 4], ] field4 = [ [1, 0, 2, 0, 0, 0, 5, 3, 4], [1, 0, 2, 0, 0, 0, 5, 3, 4], [1, 0, 2, 0, 0, 0, 5, 3, 4], [1, 0, 2, 0, 0, 0, 5, 3, 4], [1, 0, 2, 0, 0, 0, 5, 3, 4], [1, 0, 2, 0, 0, 0, 5, 3, 4], [1, 0, 2, 0, 0, 0, 5, 3, 4], [1, 0, 2, 0, 0, 0, 5.2, 3, 4], [1, 0, 2, 0, 0, 0, 5, 3, 4], ] field5 = [ [1, 0, 2, 0, 0, 0, 5, 3, 4], [1, 0, 2, 0, 0, 0, 5, 3, 4], [1, 0, 2, 0, 0, 0, 5, 3, 4], [1, 0, 2, 0, 0, 0, 5, 3, 4], [1, 0, 2, 0, 0, 0, "0", 3, 4], [1, 0, 2, 0, 0, 0, 5, 3, 4], [1, 0, 2, 0, 0, 0, 5, 3, 4], [1, 0, 2, 0, 0, 0, 5, 3, 4], [1, 0, 2, 0, 0, 0, 5, 3, 4], ] field6 = [ [1, 0, 2, 0, 0, 0, 5, 3, 4], [1, 0, 2, 0, 0, 0, 5, 3, 4], [1, 0, 2, 0, 0, 0, 5, 3, 4], [1, 0, 2, 0, 0, 0, 5, 3, 4], "this is not a list", [1, 0, 2, 0, 0, 0, 5, 3, 4], [1, 0, 2, 0, 0, 0, 5, 3, 4], [1, 0, 2, 0, 0, 0, 5, 3, 4], [1, 0, 2, 0, 0, 0, 5, 3, 4], ] field7 = [ [1, 0, 2, 0, 0, 0, 5, 3, 4], [1, 0, 2, 0, 0, 0, 5, 3, 4], [1, 0, 2, 0, 0, 0, 5, 3, 4], [1, 0, 2, 0, 0, 0, 5, 3, 4], [1, 0, 2, 0, 0, 0, 5, 3, 4], [1, 0, 2, 0, 0, 0, 5, 3, 4], [1, 0, 2, 0, 0, 0, 5, 3, 4], [1, 0, 2, 0, 0, 0, 10, 3, 4], [1, 0, 2, 0, 0, 0, 5, 3, 4], ] self.assertEqual(Validator.is_9x9_integers_field(field1), False) self.assertEqual(Validator.is_9x9_integers_field(field2), False) self.assertEqual(Validator.is_9x9_integers_field(field3), False) self.assertEqual(Validator.is_9x9_integers_field(field4), False) self.assertEqual(Validator.is_9x9_integers_field(field5), False) self.assertEqual(Validator.is_9x9_integers_field(field6), False) self.assertEqual(Validator.is_9x9_integers_field(field7), False)
def print_sudoku(matrix): if Validator.is_9x9_integers_field(matrix): for i in matrix: print(i)