Skip to content

Commit

Permalink
proper constraint tracking; simple (not yet active) solving
Browse files Browse the repository at this point in the history
  • Loading branch information
moritz committed Sep 21, 2010
1 parent de392cd commit df7f317
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 12 deletions.
58 changes: 47 additions & 11 deletions lib/Sudoku.pm
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -4,43 +4,51 @@ class Sudoku::Constraint {
has @.x; has @.x;
has @.y; # ;; has @.y; # ;;
has %.remaining-symbols handles delete-symbol => 'delete'; has %.remaining-symbols handles delete-symbol => 'delete';
method xy() { @!x Z @!y };
method Str {
' Constraint: x(' ~ @!x ~ '); y(' ~ @!y ~ ') '
~ %!remaining-symbols.keys.sort
~ "\n";
}
} }


class Sudoku { class Sudoku {
has $.block-size = 3; has $.block-size = 3;
has $.size = $.block-size ** 2; has $.size = $.block-size ** 2;
has @.rows; has @.rows;
has @!coverage;


has @!maybe; has @.constraints;
has @!constraints;


method from-string($s) { method from-string($s) {
my $o = self.new(rows => $s.comb(/.**9/).map: { [ .comb.map: +* ] }); my $o = self.new(rows => (^9).map: {[0 xx 9]});
$o.init(); $o.init();
for ^$o.size X ^$o.size -> $y, $x {
my $i = 9 * $y + $x;
if $s.substr($i, 1) -> $char {
$o.add-hint($char, :$x, :$y);
}
}
$o; $o;
} }


method Str { method Str {
@!rows.map({ .map({ $_ == 0 ?? '.' !! $_ }).join ~ "\n" }).join; @!rows.map({ .map({ $_ == 0 ?? '.' !! $_ }).join ~ "\n" }).join;
} }


method add-number($n, :$x, :$y) { method add-hint($n, :$x, :$y) {
given @!rows[$y][$x] { given @!rows[$y][$x] {
if $_ && $_ !== $n { if $_ && $_ !== $n {
die "Trying to set ($x, $y) to $n, but it is already set (to $_)"; die "Trying to set ($x, $y) to $n, but it is already set (to $_)";
} }
} }
@!constraints[$y][$y] = [0 xx $!size]; @!rows[$y][$x] = $n;
for ^$!size { for @(@!coverage[$y][$x]) {
@!constraints[$y][$_][$n - 1] = 0; .delete-symbol($n);
@!constraints[$_][$x][$n - 1] = 0;
} }
} }


method init() { method init() {
for ^$!size X ^$!size -> $x, $y {
@!constraints[$y][$x] = [ True xx $!size ];
}
for ^$!size { for ^$!size {
# rows # rows
@!constraints.push: Sudoku::Constraint.new( @!constraints.push: Sudoku::Constraint.new(
Expand All @@ -56,12 +64,40 @@ class Sudoku {
); );
} }
for ^$!block-size X ^$!block-size -> $x, $y { for ^$!block-size X ^$!block-size -> $x, $y {
# blocks
@!constraints.push: Sudoku::Constraint.new( @!constraints.push: Sudoku::Constraint.new(
x => (^$!block-size X+ ($x * $!block-size)) xx $!block-size, x => (^$!block-size X+ ($x * $!block-size)) xx $!block-size,
y => ((^$!block-size Xxx $!block-size )X+ ($y * $!block-size)), y => ((^$!block-size Xxx $!block-size )X+ ($y * $!block-size)),
remaining-symbols => hash( 1..$!size Z=> True xx * ), remaining-symbols => hash( 1..$!size Z=> True xx * ),
); );
} }
for @!constraints -> $c {
for $c.xy -> $x, $y {
@!coverage[$y][$x] //= [];
@!coverage[$y][$x].push: $c;
}
}
}

method solve() {
$.simple-fill();
}

method simple-fill() {
for @!constraints -> $c {
my @rc = $c.remaining-symbols.keys;
if @rc == 1 {
# just one remaining symbol
# find out where it is
for $c.xy -> $x, $y {
if @!rows[$y][$x] == 0 {
say "Adding @rc[0] to ($x, $y)";
$.add-hint(@rc[0], :$x, :$y);
last;
}
}
}
}
} }
} }


Expand Down
5 changes: 4 additions & 1 deletion test.pl
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -19,4 +19,7 @@


my $s = Sudoku.from-string($puzzle); my $s = Sudoku.from-string($puzzle);
say $s; say $s;
say $s.perl; say $s.constraints;
$s.solve();
say $s;
#say $s.perl;

0 comments on commit df7f317

Please sign in to comment.