Created
October 26, 2023 09:24
-
-
Save deepakkumarnd/a2f3a450823b2338fcfcb23dc8c71d81 to your computer and use it in GitHub Desktop.
Sudoku solver python
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from texttable import Texttable | |
class Sudoku: | |
__board: list[list[int]] | |
__is_solved: bool | |
def __init__(self, grid: list[list[int]]): | |
self.__board = grid | |
self.__is_solved = False | |
@staticmethod | |
def from_line(input_line: str): | |
if not ((len(input_line) == 81) and input_line.isdigit()): | |
raise Exception("Invalid sudoku puzzle") | |
grid = [] | |
for i in range(0, 80, 9): | |
grid.append([*input_line[i:i + 9]]) | |
return Sudoku(grid) | |
def __str__(self): | |
t = Texttable() | |
grid = [] | |
for row in self.__board: | |
new_row = [] | |
for col in row: | |
if col == "0": | |
new_row.append(" ") | |
else: | |
new_row.append(str(col)) | |
grid.append(new_row) | |
t.add_rows(grid, header=None) | |
return t.draw() | |
def __exists_in_same_row(self, value, row_index): | |
current_row = self.__board[row_index] | |
return str(value) in current_row | |
def __exists_in_same_column(self, value, col_index): | |
current_column = [] | |
for i in range(0, 9): | |
current_column.append(self.__board[i][col_index]) | |
return str(value) in current_column | |
def __exists_in_same_subgrid(self, value, row, col): | |
base_x = 3 * int(row / 3) | |
base_y = 3 * int(col / 3) | |
subgrid_values = [] | |
for i in range(0, 3): | |
for j in range(0, 3): | |
subgrid_values.append(self.__board[base_x + i][base_y + j]) | |
return str(value) in subgrid_values | |
def __is_valid_rows(self): | |
for row in self.__board: | |
for n in range(1, 10): | |
if not (str(n) in row): | |
return False | |
return True | |
def __is_valid_columns(self): | |
for j in range(0, 9): | |
column = [] | |
for i in range(0, 9): | |
column.append(self.__board[i][j]) | |
for n in range(1, 10): | |
if not (str(n) in column): | |
return False | |
return True | |
def __is_valid_3x3_grids(self): | |
for x in range(0, 3): | |
for y in range(0, 3): | |
sub_grid = [] | |
for i in range(0, 3): | |
for j in range(0, 3): | |
sub_grid.append(self.__board[3 * x + i][3 * y + j]) | |
for n in range(1, 10): | |
if not (str(n) in sub_grid): | |
return False | |
return True | |
def is_solved(self): | |
if not self.__is_solved: | |
self.__is_solved = self.__is_valid_rows() and self.__is_valid_columns() and self.__is_valid_3x3_grids() | |
return self.__is_solved | |
def solve(self): | |
if self.is_solved(): | |
return | |
for i in range(0, 9): | |
for j in range(0, 9): | |
if self.__board[i][j] == "0": | |
for try_value in range(1, 10): | |
if (self.__exists_in_same_row(try_value, i) or | |
self.__exists_in_same_column(try_value, j) or | |
self.__exists_in_same_subgrid(try_value, i, j)): | |
continue | |
else: | |
self.__board[i][j] = str(try_value) | |
self.solve() | |
if self.is_solved(): | |
return; | |
else: | |
self.__board[i][j] = "0" | |
if self.__board[i][j] == "0": # solution does not exists in this route | |
return | |
if __name__ == '__main__': | |
sudoku = Sudoku.from_line( | |
"580403010600050394034000050340019000000567483000040000050000030010070000002130800") | |
print(sudoku) | |
sudoku.solve() | |
print("Solution") | |
print(sudoku) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment