sudoku_solver.sf 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. #!/usr/bin/ruby
  2. # Recursive brute-force Sudoku solver.
  3. # See also:
  4. # https://rosettacode.org/wiki/Sudoku
  5. # https://en.wikipedia.org/wiki/Sudoku
  6. func check(i, j) is cached {
  7. var (id, im) = i.divmod(9)
  8. var (jd, jm) = j.divmod(9)
  9. jd == id && return true
  10. jm == im && return true
  11. (id//3 == jd//3) &&
  12. (jm//3 == im//3)
  13. }
  14. var lookup = []
  15. for i in (^81), j in (^81) {
  16. lookup[i][j] = check(i, j)
  17. }
  18. func solve_sudoku(callback, grid) {
  19. var digits = @(1..9)
  20. func {
  21. grid.each_kv {|i,v|
  22. v && next
  23. var t = Set(grid.grep_kv {|j| lookup[i][j] }...)
  24. digits.each {|d|
  25. t.has(d) && next
  26. grid[i] = d
  27. __FUNC__()
  28. grid[i] = 0
  29. }
  30. return nil
  31. }
  32. callback(grid)
  33. }()
  34. }
  35. func display_grid(grid) {
  36. say "Solution:"
  37. for i in ^grid {
  38. print "#{grid[i]} "
  39. print " " if ( 3 -> divides(i+1))
  40. print "\n" if ( 9 -> divides(i+1))
  41. print "\n" if (27 -> divides(i+1))
  42. }
  43. }
  44. var sudoku_board = %n(
  45. 5 3 0 0 2 4 7 0 0
  46. 0 0 2 0 0 0 8 0 0
  47. 1 0 0 7 0 3 9 0 2
  48. 0 0 8 0 7 2 0 4 9
  49. 0 2 0 9 8 0 0 7 0
  50. 7 9 0 0 0 0 0 8 0
  51. 0 0 0 0 3 0 5 0 6
  52. 9 6 0 0 1 0 3 0 0
  53. 0 5 0 6 9 0 0 1 0
  54. )
  55. sudoku_board = %n(
  56. 0 0 0 8 0 1 0 0 0
  57. 0 0 0 0 0 0 0 4 3
  58. 5 0 0 0 0 0 0 0 0
  59. 0 0 0 0 7 0 8 0 0
  60. 0 0 0 0 0 0 1 0 0
  61. 0 2 0 0 3 0 0 0 0
  62. 6 0 0 0 0 0 0 7 5
  63. 0 0 3 4 0 0 0 0 0
  64. 0 0 0 2 0 0 6 0 0
  65. ) if false
  66. sudoku_board = %n(
  67. 8 0 0 0 0 0 0 0 0
  68. 0 0 3 6 0 0 0 0 0
  69. 0 7 0 0 9 0 2 0 0
  70. 0 5 0 0 0 7 0 0 0
  71. 0 0 0 0 4 5 7 0 0
  72. 0 0 0 1 0 0 0 3 0
  73. 0 0 1 0 0 0 0 6 8
  74. 0 0 8 5 0 0 0 1 0
  75. 0 9 0 0 0 0 4 0 0
  76. ) if false
  77. solve_sudoku(display_grid, sudoku_board)