096 Su Doku.pl 1.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
  1. #!/usr/bin/perl
  2. # Daniel "Trizen" Șuteu
  3. # License: GPLv3
  4. # Date: 30 January 2017
  5. # https://github.com/trizen
  6. # https://projecteuler.net/problem=96
  7. # Runtime: 13.888s
  8. use 5.016;
  9. use strict;
  10. use integer;
  11. sub check {
  12. my ($i, $j) = @_;
  13. my ($id, $im) = ($i / 9, $i % 9);
  14. my ($jd, $jm) = ($j / 9, $j % 9);
  15. $jd == $id && return 1;
  16. $jm == $im && return 1;
  17. $id / 3 == $jd / 3 and
  18. $jm / 3 == $im / 3;
  19. }
  20. my @lookup;
  21. foreach my $i (0 .. 80) {
  22. foreach my $j (0 .. 80) {
  23. $lookup[$i][$j] = check($i, $j);
  24. }
  25. }
  26. sub solve_sudoku {
  27. my ($callback, @grid) = @_;
  28. sub {
  29. foreach my $i (0 .. 80) {
  30. if (!$grid[$i]) {
  31. my %t;
  32. undef @t{@grid[grep { $lookup[$i][$_] } 0 .. 80]};
  33. foreach my $k (1 .. 9) {
  34. if (not exists $t{$k}) {
  35. $grid[$i] = $k;
  36. __SUB__->();
  37. }
  38. }
  39. $grid[$i] = 0;
  40. return;
  41. }
  42. }
  43. $callback->(@grid);
  44. goto SOLUTION_FOUND;
  45. }->();
  46. SOLUTION_FOUND: return;
  47. }
  48. open my $fh, '<:raw', ($ARGV[0] // 'p096_sudoku.txt')
  49. or die "Can't open file `p096_sudoku.txt`: $!";
  50. chomp(my @grids = grep { /^[0-9]+$/ } <$fh>);
  51. close $fh;
  52. my $sum = 0;
  53. while (@grids) {
  54. my @grid = split(//, join('', splice(@grids, 0, 9)));
  55. solve_sudoku(sub { $sum += "$_[0]$_[1]$_[2]" }, @grid);
  56. }
  57. say $sum;