مقدمه
سودوکو یک بازی منطقی است که در آن باید یک جدول ۹ در ۹ را به گونهای پر کنید که هر سطر، هر ستون و هر بلوک ۳ در ۳ آن شامل اعداد ۱ تا ۹ باشد. برای حل سودوکو با پایتون، میتوانید از الگوریتمهای مختلفی استفاده کنید. الگوریتم backtracking یکی از رایجترین الگوریتمها برای حل سودوکو است. در این الگوریتم، ابتدا به دنبال خانهای خالی میگردیم و سپس به ترتیب اعداد را در آن قرار میدهیم و با استفاده از backtracking، به دنبال راه حل مسئله میگردیم.
تابع solve_sudoku
تابع solve_sudoku تابع اصلی است که تلاش میکند تا پازل سودوکو را حل کند. آرگومان ورودی آن یک لیست دوبعدی board است که شبکه سودوکو را نشان میدهد.
def solve_sudoku(board):
# Find the next empty cell
empty_cell = find_empty_cell(board)
# If there are no more empty cells, the Sudoku is solved
if not empty_cell:
return True
# Try different numbers in the empty cell
for num in range(1, 10):
if is_valid(board, empty_cell, num):
# Place the number in the empty cell
board[empty_cell[0]][empty_cell[1]] = num
# Recursively solve the Sudoku
if solve_sudoku(board):
return True
# If the current number doesn't lead to a solution, backtrack
board[empty_cell[0]][empty_cell[1]] = 0
# If no numbers work, the Sudoku is unsolvable
return False
تابع find_empty_cell
تابع find_empty_cell سلول خالی بعدی (که با صفر نشان داده میشود) در شبکه سودوکو را پیدا میکند. این تابع روی هر سلول حرکت میکند و مختصات اولین سلول خالی که برخورد میکند را برمیگرداند. اگر هیچ سلول خالی پیدا نشود، None برگردانده میشود.
def find_empty_cell(board):
# Find the next empty cell represented by 0
for row in range(9):
for col in range(9):
if board[col] == 0:
return (row, col)
return None
تابع is_valid
تابع is_valid بررسی میکند که آیا یک عدد num در مکان مشخصی (row، col) در شبکه سودوکو قرار گرفتن معتبر است یا خیر. این تابع بررسی میکند آیا عدد در همان ردیف، ستون یا شبکه ۳x۳ حاضر است یا خیر. اگر عدد در تمام این شرایط نقض ایجاد کند، تابع مقدار False را برمیگرداند که نشان میدهد عدد معتبر نیست. در غیر این صورت، True برگردانده میشود.
def is_valid(board, position, num):
# Check if the number is valid in the row
for col in range(9):
if board[position[0]][col] == num and position[1] != col:
return False
# Check if the number is valid in the column
for row in range(9):
if board[position[1]] == num and position[0] != row:
return False
# Check if the number is valid in the 3x3 grid
box_row = position[0] // 3
box_col = position[1] // 3
for row in range(box_row * 3, box_row * 3 + 3):
for col in range(box_col * 3, box_col * 3 + 3):
if board[col] == num and (row, col) != position:
return False
return True
تابع is_valid
تابع is_valid بررسی میکند که آیا یک عدد num در مکان مشخصی (row، col) در شبکه سودوکو قرار گرفتن معتبر است یا خیر. این تابع بررسی میکند آیا عدد در همان ردیف، ستون یا شبکه ۳x۳ حاضر است یا خیر. اگر عدد در تمام این شرایط نقض ایجاد کند، تابع مقدار False را برمیگرداند که نشان میدهد عدد معتبر نیست. در غیر این صورت، True برگردانده میشود.
def solve_sudoku(board):
# Find the next empty cell
empty_cell = find_empty_cell(board)
# If there are no more empty cells, the Sudoku is solved
if not empty_cell:
return True
# Try different numbers in the empty cell
for num in range(1, 10):
if is_valid(board, empty_cell, num):
# Place the number in the empty cell
board[empty_cell[0]][empty_cell[1]] = num
# Recursively solve the Sudoku
if solve_sudoku(board):
return True
# If the current number doesn't lead to a solution, backtrack
board[empty_cell[0]][empty_cell[1]] = 0
# If no numbers work, the Sudoku is unsolvable
return False
بررسی
داخل تابع solve_sudoku، ابتدا تابع find_empty_cell را فراخوانی میکند تا سلول خالی بعدی در شبکه سودوکو را پیدا کند.
اگر دیگر سلولی خالی نباشد، به این معنا است که سودوکو به طور کامل پر شده است و به این ترتیب، تابع مقدار True را برمیگرداند تا حل موفق را نشان دهد.
اگر یک سلول خالی وجود داشته باشد، تابع وارد یک حلقه میشود که برای هر عدد (از ۱ تا ۹)، آن عدد را در سلول خالی تلاش میکند.
برای هر عدد، با استفاده از تابع is_valid، بررسی میشود که آیا عدد در موقعیت سلول خالی معتبر است یا خیر. اگر عدد معتبر باشد، عدد را در سلول خالی قرار میدهد.
سپس، به صورت بازگشتی تابع solve_sudoku را فراخوانی میکند تا با استفاده از شبکه بروزرسانی شده، ادامه حل سودوکو را ادامه دهد.
اگر فراخوانی بازگشتی مقدار True برگرداند، به این معناست که یک پاسخ پیدا شده است، بنابراین تابع مقدار True را برمیگرداند تا موفقیت را به فراخوانی اولیه منتقل کند.
اگر فراخوانی بازگشتی مقدار False برگرداند، به این معناست که انتخاب فعلی عدد به یافتن یک پاسخ منجر نمیشود. در این حالت، تابع با بازنشانی سلول خالی فعلی به مقدار ۰، به عقب برمیگردد و با عدد بعدی در حلقه ادامه مییابد.
اگر هیچکدام از اعداد (از ۱ تا ۹) برای سلول خالی فعلی کار نکند، تابع مقدار False را برمیگرداند که نشان میدهد که سودوکو قابل حل نیست.
در پایان، پس از فراخوانی solve_sudoku(board)، شبکه حل شده سودوکو به صورت سطر به سطر با استفاده از یک حلقه ساده چاپ میشود.
برای استفاده از حلکننده، میتوانید یک شبکه سودوکو را به عنوان یک لیست دوبعدی ارائه دهید، جایی که سلولهای خالی با صفر نشان داده میشوند. پس از فراخوانی solve_sudoku(board)، شبکه اصلی با مقادیر حل شده تغییر خواهد کرد و میتوانید آن را چاپ کنید تا پاسخ را ببینید.
کد کامل پایتونی این برنامه
def solve_sudoku(board):
# Find the next empty cell
empty_cell = find_empty_cell(board)
# If there are no more empty cells, the Sudoku is solved
if not empty_cell:
return True
# Try different numbers in the empty cell
for num in range(1, 10):
if is_valid(board, empty_cell, num):
# Place the number in the empty cell
board[empty_cell[0]][empty_cell[1]] = num
# Recursively solve the Sudoku
if solve_sudoku(board):
return True
# If the current number doesn't lead to a solution, backtrack
board[empty_cell[0]][empty_cell[1]] = 0
# If no numbers work, the Sudoku is unsolvable
return False
def find_empty_cell(board):
# Find the next empty cell represented by 0
for row in range(9):
for col in range(9):
if board[col] == 0:
return (row, col)
return None
def is_valid(board, position, num):
# Check if the number is valid in the row
for col in range(9):
if board[position[0]][col] == num and position[1] != col:
return False
# Check if the number is valid in the column
for row in range(9):
if board[position[1]] == num and position[0] != row:
return False
# Check if the number is valid in the 3x3 grid
box_row = position[0] // 3
box_col = position[1] // 3
for row in range(box_row * 3, box_row * 3 + 3):
for col in range(box_col * 3, box_col * 3 + 3):
if board[col] == num and (row, col) != position:
return False
return True
# Example usage
board = [
[5, 3, 0, 0, 7, 0, 0, 0, 0],
[6, 0, 0, 1, 9, 5, 0, 0, 0],
[0, 9, 8, 0, 0, 0, 0, 6, 0],
[8, 0, 0, 0, 6, 0, 0, 0, 3],
[4, 0, 0, 8, 0, 3, 0, 0, 1],
[7, 0, 0, 0, 2, 0, 0, 0, 6],
[0, 6, 0, 0, 0, 0, 2, 8, 0],
[0, 0, 0, 4, 1, 9, 0, 0, 5],
[0, 0, 0, 0, 8, 0, 0, 7, 9]
]
solve_sudoku(board)
# Print the solved Sudoku
for row in board:
print(row)
برای نوشتن دیدگاه باید وارد بشوید.