sudoku_solver.pl 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. #!/usr/bin/perl
  2. # Daniel "Trizen" Șuteu
  3. # License: GPLv3
  4. # Date: 30 January 2017
  5. # https://github.com/trizen
  6. # Recursive brute-force Sudoku solver.
  7. # See also:
  8. # https://en.wikipedia.org/wiki/Sudoku
  9. use 5.016;
  10. use strict;
  11. sub check {
  12. my ($i, $j) = @_;
  13. use integer;
  14. my ($id, $im) = ($i / 9, $i % 9);
  15. my ($jd, $jm) = ($j / 9, $j % 9);
  16. $jd == $id && return 1;
  17. $jm == $im && return 1;
  18. $id / 3 == $jd / 3
  19. and $jm / 3 == $im / 3;
  20. }
  21. my @lookup;
  22. foreach my $i (0 .. 80) {
  23. foreach my $j (0 .. 80) {
  24. $lookup[$i][$j] = check($i, $j);
  25. }
  26. }
  27. sub solve_sudoku {
  28. my ($callback, @grid) = @_;
  29. sub {
  30. foreach my $i (0 .. 80) {
  31. if (!$grid[$i]) {
  32. my %t;
  33. undef @t{@grid[grep { $lookup[$i][$_] } 0 .. 80]};
  34. foreach my $k (1 .. 9) {
  35. if (!exists $t{$k}) {
  36. $grid[$i] = $k;
  37. __SUB__->();
  38. $grid[$i] = 0;
  39. }
  40. }
  41. return;
  42. }
  43. }
  44. $callback->(@grid);
  45. }->();
  46. }
  47. #<<<
  48. my @grid = qw(
  49. 5 3 0 0 7 0 0 0 0
  50. 6 0 0 1 9 5 0 0 0
  51. 0 9 8 0 0 0 0 6 0
  52. 8 0 0 0 6 0 0 0 3
  53. 4 0 0 8 0 3 0 0 1
  54. 7 0 0 0 2 0 0 0 6
  55. 0 6 0 0 0 0 2 8 0
  56. 0 0 0 4 1 9 0 0 5
  57. 0 0 0 0 8 0 0 7 9
  58. );
  59. @grid = qw(
  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. ) if 0;
  70. @grid = qw(
  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. ) if 0;
  81. #>>>
  82. solve_sudoku(
  83. sub {
  84. say "Solution:";
  85. my (@solution) = @_;
  86. foreach my $i (0 .. $#solution) {
  87. print "$solution[$i] ";
  88. print " " if ($i + 1) % 3 == 0;
  89. print "\n" if ($i + 1) % 9 == 0;
  90. print "\n" if ($i + 1) % 27 == 0;
  91. }
  92. }, @grid
  93. );