sudoku_solver_backtracking.sf 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. #!/usr/bin/ruby
  2. # Solve Sudoku puzzle (recursive solution).
  3. func is_valid(board, row, col, num) {
  4. # Check if the number is not present in the current row and column
  5. for i in ^9 {
  6. if ((board[row][i] == num) || (board[i][col] == num)) {
  7. return false
  8. }
  9. }
  10. # Check if the number is not present in the current 3x3 subgrid
  11. var (start_row, start_col) = (3*idiv(row, 3), 3*idiv(col, 3))
  12. for i in ^3, j in ^3 {
  13. if (board[start_row + i][start_col + j] == num) {
  14. return false
  15. }
  16. }
  17. return true
  18. }
  19. func find_empty_location(board) {
  20. # Find an empty position (cell with 0)
  21. for i in ^9, j in ^9 {
  22. if (board[i][j] == 0) {
  23. return (i, j)
  24. }
  25. }
  26. return (nil, nil) # If the board is filled
  27. }
  28. func solve_sudoku(board) {
  29. var (row, col) = find_empty_location(board)
  30. if (!defined(row) && !defined(col)) {
  31. return true # Puzzle is solved
  32. }
  33. for num in (1..9) {
  34. if (is_valid(board, row, col, num)) {
  35. # Try placing the number
  36. board[row][col] = num
  37. # Recursively try to solve the rest of the puzzle
  38. if (__FUNC__(board)) {
  39. return true
  40. }
  41. # If placing the current number doesn't lead to a solution, backtrack
  42. board[row][col] = 0
  43. }
  44. }
  45. return false # No solution found
  46. }
  47. # Example usage:
  48. # Define the Sudoku puzzle as a 9x9 list with 0 representing empty cells
  49. var sudoku_board = %n(
  50. 2 0 0 0 7 0 0 0 3
  51. 1 0 0 0 0 0 0 8 0
  52. 0 0 4 2 0 9 0 0 5
  53. 9 4 0 0 0 0 6 0 8
  54. 0 0 0 8 0 0 0 9 0
  55. 0 0 0 0 0 0 0 7 0
  56. 7 2 1 9 0 8 0 6 0
  57. 0 3 0 0 2 7 1 0 0
  58. 4 0 0 0 0 3 0 0 0
  59. ).slices(9)
  60. sudoku_board = %n(
  61. 0 0 0 8 0 1 0 0 0
  62. 0 0 0 0 0 0 0 4 3
  63. 5 0 0 0 0 0 0 0 0
  64. 0 0 0 0 7 0 8 0 0
  65. 0 0 0 0 0 0 1 0 0
  66. 0 2 0 0 3 0 0 0 0
  67. 6 0 0 0 0 0 0 7 5
  68. 0 0 3 4 0 0 0 0 0
  69. 0 0 0 2 0 0 6 0 0
  70. ).slices(9) if false
  71. sudoku_board = %n(
  72. 8 0 0 0 0 0 0 0 0
  73. 0 0 3 6 0 0 0 0 0
  74. 0 7 0 0 9 0 2 0 0
  75. 0 5 0 0 0 7 0 0 0
  76. 0 0 0 0 4 5 7 0 0
  77. 0 0 0 1 0 0 0 3 0
  78. 0 0 1 0 0 0 0 6 8
  79. 0 0 8 5 0 0 0 1 0
  80. 0 9 0 0 0 0 4 0 0
  81. ).slices(9) if false
  82. func display_grid(grid) {
  83. for i in ^grid {
  84. print "#{grid[i]} "
  85. print " " if ( 3 -> divides(i+1))
  86. print "\n" if ( 9 -> divides(i+1))
  87. print "\n" if (27 -> divides(i+1))
  88. }
  89. }
  90. if (solve_sudoku(sudoku_board)) {
  91. display_grid(sudoku_board.flat)
  92. }
  93. else {
  94. say "No solution exists."
  95. }