sudoku_solver_stack.sf 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. #!/usr/bin/ruby
  2. # Solve Sudoku puzzle (iterative solution // stack-based).
  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 stack = [board]
  30. while (stack) {
  31. var current_board = stack.pop
  32. var (row, col) = find_empty_location(current_board)
  33. if (!defined(row) && !defined(col)) {
  34. return current_board
  35. }
  36. for num in (1..9) {
  37. if (is_valid(current_board, row, col, num)) {
  38. var new_board = current_board.map { .clone }
  39. new_board[row][col] = num
  40. stack << new_board
  41. }
  42. }
  43. }
  44. return nil
  45. }
  46. # Example usage:
  47. # Define the Sudoku puzzle as a 9x9 list with 0 representing empty cells
  48. var sudoku_board = %n(
  49. 2 0 0 0 7 0 0 0 3
  50. 1 0 0 0 0 0 0 8 0
  51. 0 0 4 2 0 9 0 0 5
  52. 9 4 0 0 0 0 6 0 8
  53. 0 0 0 8 0 0 0 9 0
  54. 0 0 0 0 0 0 0 7 0
  55. 7 2 1 9 0 8 0 6 0
  56. 0 3 0 0 2 7 1 0 0
  57. 4 0 0 0 0 3 0 0 0
  58. ).slices(9)
  59. sudoku_board = %n(
  60. 0 0 0 8 0 1 0 0 0
  61. 0 0 0 0 0 0 0 4 3
  62. 5 0 0 0 0 0 0 0 0
  63. 0 0 0 0 7 0 8 0 0
  64. 0 0 0 0 0 0 1 0 0
  65. 0 2 0 0 3 0 0 0 0
  66. 6 0 0 0 0 0 0 7 5
  67. 0 0 3 4 0 0 0 0 0
  68. 0 0 0 2 0 0 6 0 0
  69. ).slices(9) if false
  70. sudoku_board = %n(
  71. 8 0 0 0 0 0 0 0 0
  72. 0 0 3 6 0 0 0 0 0
  73. 0 7 0 0 9 0 2 0 0
  74. 0 5 0 0 0 7 0 0 0
  75. 0 0 0 0 4 5 7 0 0
  76. 0 0 0 1 0 0 0 3 0
  77. 0 0 1 0 0 0 0 6 8
  78. 0 0 8 5 0 0 0 1 0
  79. 0 9 0 0 0 0 4 0 0
  80. ).slices(9) if false
  81. func display_grid(grid) {
  82. for i in ^grid {
  83. print "#{grid[i]} "
  84. print " " if ( 3 -> divides(i+1))
  85. print "\n" if ( 9 -> divides(i+1))
  86. print "\n" if (27 -> divides(i+1))
  87. }
  88. }
  89. var solution = solve_sudoku(sudoku_board)
  90. if (solution) {
  91. display_grid(solution.flat)
  92. }
  93. else {
  94. say "No solution exists."
  95. }