=head1 NAME nondet_sudoku.pl - A non deterministic sudoku solver =head1 DESCRIPTION A non-working perl 6 implementation of a non deterministic sudoku solver. Once we have full continuations, I'll revisit this and add a proper UI, right now it's simply a demonstration of possibility. =head1 AUTHOR Piers Cawley Epdcawley@bofh.org.ukE =head1 COPYRIGHT Copyright (c) 2005. Piers Cawley. All rights reserved. This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself. See http://www.perl.com/perl/misc/Artistic.html =cut use v6-alpha; sub callcc (Code &block) { &block(&?CALLER_CONTINUATION) } my &give_up = sub { die "Program failed" }; sub choose (*@all_choices) { my &old_give_up = &give_up; callcc -> $cnt { my $try = -> @choices { if ! @choices { &give_up = &old_give_up; give_up; } else { my($choice, @newchoices) = @choices; &give_up = sub { $cnt($try(@newchoices)) }; $choice; } }; $try(@all_choices); }; } sub newchoose (*@all_choices) { my &old_give_up = &give_up; { my $try = -> @choices { if ! @choices { &give_up = &old_give_up; give_up } else { my ($choice, @newchoices) = @choices; &give_up = -> { return $try(@newchoices) }; $choice; } }; $try(@all_choices); }; } # Solve a 4x4 sudoku my @grid = ( [ choose(1..4), choose(1..4), 2, choose(1..4) ], [ 1, choose(1..4), choose(1..4), choose(1..4) ], [ choose(1..4), choose(1..4), choose(1..4), 3 ], [ choose(1..4), 4, choose(1..4), choose(1..4) ] ); # Row assertions give_up unless @grid[0].uniq == 4; give_up unless @grid[1].uniq == 4; give_up unless @grid[2].uniq == 4; give_up unless @grid[3].uniq == 4; # Column assertions give_up unless [map -> $a {$a[0]}, @grid[0..3]].uniq == 4; give_up unless [map -> $a {$a[1]}, @grid[0..3]].uniq == 4; give_up unless [map -> $a {$a[2]}, @grid[0..3]].uniq == 4; give_up unless [map -> $a {$a[3]}, @grid[0..3]].uniq == 4; # Subgrid assertions give_up unless [@grid[0][0], @grid[0][1], @grid[1][0], @grid[1][1]].uniq == 4; give_up unless [@grid[0][2], @grid[0][3], @grid[1][2], @grid[1][3]].uniq == 4; give_up unless [@grid[2][0], @grid[2][1], @grid[3][0], @grid[3][1]].uniq == 4; give_up unless [@grid[2][2], @grid[2][3], @grid[3][2], @grid[3][3]].uniq == 4; for @grid -> @row { say @row };