mirror of
https://github.com/TheAlgorithms/Python.git
synced 2025-07-05 17:34:49 +08:00
[mypy] Add/fix type annotations for backtracking algorithms (#4055)
* Fix mypy errors for backtracking algorithms * Fix CI failure
This commit is contained in:
@ -1,20 +1,20 @@
|
||||
from typing import List, Tuple, Union
|
||||
"""
|
||||
Given a partially filled 9×9 2D array, the objective is to fill a 9×9
|
||||
square grid with digits numbered 1 to 9, so that every row, column, and
|
||||
and each of the nine 3×3 sub-grids contains all of the digits.
|
||||
|
||||
This can be solved using Backtracking and is similar to n-queens.
|
||||
We check to see if a cell is safe or not and recursively call the
|
||||
function on the next column to see if it returns True. if yes, we
|
||||
have solved the puzzle. else, we backtrack and place another number
|
||||
in that cell and repeat this process.
|
||||
"""
|
||||
from typing import List, Optional, Tuple
|
||||
|
||||
Matrix = List[List[int]]
|
||||
|
||||
"""
|
||||
Given a partially filled 9×9 2D array, the objective is to fill a 9×9
|
||||
square grid with digits numbered 1 to 9, so that every row, column, and
|
||||
and each of the nine 3×3 sub-grids contains all of the digits.
|
||||
|
||||
This can be solved using Backtracking and is similar to n-queens.
|
||||
We check to see if a cell is safe or not and recursively call the
|
||||
function on the next column to see if it returns True. if yes, we
|
||||
have solved the puzzle. else, we backtrack and place another number
|
||||
in that cell and repeat this process.
|
||||
"""
|
||||
# assigning initial values to the grid
|
||||
initial_grid = [
|
||||
initial_grid: Matrix = [
|
||||
[3, 0, 6, 5, 0, 8, 4, 0, 0],
|
||||
[5, 2, 0, 0, 0, 0, 0, 0, 0],
|
||||
[0, 8, 7, 0, 0, 0, 0, 3, 1],
|
||||
@ -27,7 +27,7 @@ initial_grid = [
|
||||
]
|
||||
|
||||
# a grid with no solution
|
||||
no_solution = [
|
||||
no_solution: Matrix = [
|
||||
[5, 0, 6, 5, 0, 8, 4, 0, 3],
|
||||
[5, 2, 0, 0, 0, 0, 0, 0, 2],
|
||||
[1, 8, 7, 0, 0, 0, 0, 3, 1],
|
||||
@ -80,7 +80,7 @@ def is_completed(grid: Matrix) -> bool:
|
||||
return all(all(cell != 0 for cell in row) for row in grid)
|
||||
|
||||
|
||||
def find_empty_location(grid: Matrix) -> Tuple[int, int]:
|
||||
def find_empty_location(grid: Matrix) -> Optional[Tuple[int, int]]:
|
||||
"""
|
||||
This function finds an empty location so that we can assign a number
|
||||
for that particular row and column.
|
||||
@ -89,9 +89,10 @@ def find_empty_location(grid: Matrix) -> Tuple[int, int]:
|
||||
for j in range(9):
|
||||
if grid[i][j] == 0:
|
||||
return i, j
|
||||
return None
|
||||
|
||||
|
||||
def sudoku(grid: Matrix) -> Union[Matrix, bool]:
|
||||
def sudoku(grid: Matrix) -> Optional[Matrix]:
|
||||
"""
|
||||
Takes a partially filled-in grid and attempts to assign values to
|
||||
all unassigned locations in such a way to meet the requirements
|
||||
@ -107,25 +108,30 @@ def sudoku(grid: Matrix) -> Union[Matrix, bool]:
|
||||
[1, 3, 8, 9, 4, 7, 2, 5, 6],
|
||||
[6, 9, 2, 3, 5, 1, 8, 7, 4],
|
||||
[7, 4, 5, 2, 8, 6, 3, 1, 9]]
|
||||
>>> sudoku(no_solution)
|
||||
False
|
||||
>>> sudoku(no_solution) is None
|
||||
True
|
||||
"""
|
||||
|
||||
if is_completed(grid):
|
||||
return grid
|
||||
|
||||
row, column = find_empty_location(grid)
|
||||
location = find_empty_location(grid)
|
||||
if location is not None:
|
||||
row, column = location
|
||||
else:
|
||||
# If the location is ``None``, then the grid is solved.
|
||||
return grid
|
||||
|
||||
for digit in range(1, 10):
|
||||
if is_safe(grid, row, column, digit):
|
||||
grid[row][column] = digit
|
||||
|
||||
if sudoku(grid):
|
||||
if sudoku(grid) is not None:
|
||||
return grid
|
||||
|
||||
grid[row][column] = 0
|
||||
|
||||
return False
|
||||
return None
|
||||
|
||||
|
||||
def print_solution(grid: Matrix) -> None:
|
||||
@ -141,11 +147,12 @@ def print_solution(grid: Matrix) -> None:
|
||||
|
||||
if __name__ == "__main__":
|
||||
# make a copy of grid so that you can compare with the unmodified grid
|
||||
for grid in (initial_grid, no_solution):
|
||||
grid = list(map(list, grid))
|
||||
solution = sudoku(grid)
|
||||
if solution:
|
||||
print("grid after solving:")
|
||||
for example_grid in (initial_grid, no_solution):
|
||||
print("\nExample grid:\n" + "=" * 20)
|
||||
print_solution(example_grid)
|
||||
print("\nExample grid solution:")
|
||||
solution = sudoku(example_grid)
|
||||
if solution is not None:
|
||||
print_solution(solution)
|
||||
else:
|
||||
print("Cannot find a solution.")
|
||||
|
Reference in New Issue
Block a user