personalspace / sudoku_solver.py
ravim254's picture
Upload 3 files
a0e2f98 verified
import tkinter as tk
from tkinter import messagebox
class SudokuSolver:
def __init__(self, grid):
self.grid = grid
def is_valid(self, row, col, num):
for i in range(9):
if self.grid[row][i] == num:
return False
if self.grid[i][col] == num:
return False
start_row, start_col = 3 * (row // 3), 3 * (col // 3)
for r in range(start_row, start_row + 3):
for c in range(start_col, start_col + 3):
if self.grid[r][c] == num:
return False
return True
def solve_logic(self):
cycles = 0
while True:
changed = False
for digit in range(1, 10):
for box_row in range(3):
for box_col in range(3):
possible = []
for r in range(box_row * 3, (box_row + 1) * 3):
for c in range(box_col * 3, (box_col + 1) * 3):
if self.grid[r][c] == 0 and self.is_valid(r, c, digit):
possible.append((r, c))
if len(possible) == 1:
r, c = possible[0]
self.grid[r][c] = digit
changed = True
cycles += 1
if not changed:
break
print(f"\n=== Logic Solve Completed After {cycles} Cycle(s) ===")
for row in self.grid:
print(row)
def solve_backtracking(self):
empty = self.find_empty()
if not empty:
return True
r, c = empty
for num in range(1, 10):
if self.is_valid(r, c, num):
self.grid[r][c] = num
if self.solve_backtracking():
return True
self.grid[r][c] = 0
return False
def find_empty(self):
for r in range(9):
for c in range(9):
if self.grid[r][c] == 0:
return (r, c)
return None
class SudokuUI:
def __init__(self, root):
self.root = root
self.root.title("Sudoku Solver (Logic + Backtracking)")
self.entries = [[None for _ in range(9)] for _ in range(9)]
self.build_grid()
self.build_buttons()
def build_grid(self):
frame = tk.Frame(self.root)
frame.pack()
for r in range(9):
for c in range(9):
e = tk.Entry(frame, width=2, font=('Arial', 18), justify='center')
e.grid(row=r, column=c, padx=(2 if c % 3 == 0 else 0), pady=(2 if r % 3 == 0 else 0))
self.entries[r][c] = e
def build_buttons(self):
btn_frame = tk.Frame(self.root)
btn_frame.pack(pady=10)
logic_btn = tk.Button(btn_frame, text="Logic Solve", command=self.logic_solve)
logic_btn.pack(side='left', padx=5)
backtrack_btn = tk.Button(btn_frame, text="Start Backtracking", command=self.backtracking_solve)
backtrack_btn.pack(side='left', padx=5)
clear_btn = tk.Button(btn_frame, text="Clear", command=self.clear)
clear_btn.pack(side='left', padx=5)
def read_grid(self):
grid = []
print("\n=== Input Grid ===")
for r in range(9):
row = []
for c in range(9):
val = self.entries[r][c].get()
if val == '':
row.append(0)
else:
try:
num = int(val)
if not (1 <= num <= 9):
raise ValueError
row.append(num)
except ValueError:
messagebox.showerror("Invalid input", f"Invalid number at row {r+1}, col {c+1}")
return None
print(row)
grid.append(row)
return grid
def write_grid(self, grid):
for r in range(9):
for c in range(9):
self.entries[r][c].delete(0, tk.END)
if grid[r][c] != 0:
self.entries[r][c].insert(0, str(grid[r][c]))
def logic_solve(self):
grid = self.read_grid()
if grid is None:
return
solver = SudokuSolver(grid)
solver.solve_logic()
self.write_grid(solver.grid)
def backtracking_solve(self):
grid = self.read_grid()
if grid is None:
return
solver = SudokuSolver(grid)
print("\nStarting backtracking...")
solver.solve_backtracking()
print("\n=== Final Solved Grid ===")
for row in solver.grid:
print(row)
self.write_grid(solver.grid)
def clear(self):
for r in range(9):
for c in range(9):
self.entries[r][c].delete(0, tk.END)
if __name__ == "__main__":
root = tk.Tk()
app = SudokuUI(root)
root.mainloop()