| line | stmt | bran | cond | sub | pod | time | code | 
| 1 |  |  |  |  |  |  | package Games::Sudoku::Kubedoku; | 
| 2 |  |  |  |  |  |  |  | 
| 3 |  |  |  |  |  |  | our $VERSION = 1.00; | 
| 4 |  |  |  |  |  |  |  | 
| 5 |  |  |  |  |  |  | sub new { | 
| 6 | 24 |  |  | 24 | 0 | 19519 | my $invocant = shift; | 
| 7 | 24 |  | 33 |  |  | 149 | my $class = ref($invocant) || $invocant; | 
| 8 |  |  |  |  |  |  | # Create the Object Data | 
| 9 | 24 |  |  |  |  | 48 | my $game = {}; | 
| 10 | 24 |  |  |  |  | 44 | my $sudoku = shift; | 
| 11 | 24 | 100 |  |  |  | 47 | if ($sudoku) { | 
| 12 | 23 |  |  |  |  | 67 | get_data_struc($game, get_size($sudoku)); | 
| 13 | 23 |  |  |  |  | 82 | set_game($game, $sudoku); | 
| 14 |  |  |  |  |  |  | } | 
| 15 |  |  |  |  |  |  | else { | 
| 16 |  |  |  |  |  |  | # Defult Game is 9x9 | 
| 17 | 1 |  |  |  |  | 4 | get_data_struc($game, 9); | 
| 18 |  |  |  |  |  |  | } | 
| 19 | 24 |  |  |  |  | 120 | bless($game, $class); | 
| 20 | 24 |  |  |  |  | 134 | return $game; | 
| 21 |  |  |  |  |  |  | } | 
| 22 |  |  |  |  |  |  |  | 
| 23 |  |  |  |  |  |  |  | 
| 24 |  |  |  |  |  |  |  | 
| 25 |  |  |  |  |  |  | ############################################################################### | 
| 26 |  |  |  |  |  |  | # Kubedoku Public Functions | 
| 27 |  |  |  |  |  |  | ############################################################################### | 
| 28 |  |  |  |  |  |  |  | 
| 29 |  |  |  |  |  |  |  | 
| 30 |  |  |  |  |  |  |  | 
| 31 |  |  |  |  |  |  | ################################################# | 
| 32 |  |  |  |  |  |  | # Set the Sudoku Values | 
| 33 |  |  |  |  |  |  | ################################################# | 
| 34 |  |  |  |  |  |  | sub set_game { | 
| 35 | 23 |  |  | 23 | 0 | 41 | my $game   = shift; | 
| 36 | 23 |  |  |  |  | 76 | my $sudoku = lc(shift); | 
| 37 | 23 |  |  |  |  | 74 | $sudoku =~ s/\s+//g; | 
| 38 | 23 |  |  |  |  | 336 | $sudoku =~ s/\./0/g; | 
| 39 | 23 | 50 |  |  |  | 105 | if (length($sudoku) != ($game->{'size'} * $game->{'size'})) { | 
| 40 | 0 |  |  |  |  | 0 | print STDERR "ERROR: Sudoku game has ".length($sudoku)." values when it should have ".($game->{'size'} * $game->{'size'})." !!!\n"; | 
| 41 | 0 |  |  |  |  | 0 | return 0; | 
| 42 |  |  |  |  |  |  | } | 
| 43 | 23 |  |  |  |  | 837 | my @sudoku = split(//, $sudoku); | 
| 44 | 23 |  |  |  |  | 165 | for (my $n=0; $n | 
| 45 | 1973 |  |  |  |  | 2803 | my $x = ($n % $game->{'size'}) + 1; | 
| 46 | 1973 |  |  |  |  | 2838 | my $y = int($n / $game->{'size'}) + 1; | 
| 47 | 1973 | 100 |  |  |  | 6113 | if ($sudoku[$n]) { | 
| 48 | 545 | 100 |  |  |  | 1362 | if ($sudoku[$n] =~ m/[a-z]/) { | 
| 49 | 42 |  |  |  |  | 96 | $sudoku[$n] = (ord($sudoku[$n]) - 87); | 
| 50 |  |  |  |  |  |  | } | 
| 51 | 545 |  |  |  |  | 983 | set_value($game, $x, $y, $sudoku[$n]); | 
| 52 |  |  |  |  |  |  | } | 
| 53 |  |  |  |  |  |  | } | 
| 54 | 23 |  |  |  |  | 329 | return 1; | 
| 55 |  |  |  |  |  |  | } | 
| 56 |  |  |  |  |  |  |  | 
| 57 |  |  |  |  |  |  | ################################################# | 
| 58 |  |  |  |  |  |  | # Get the Sudoku Values | 
| 59 |  |  |  |  |  |  | ################################################# | 
| 60 |  |  |  |  |  |  | sub get_game { | 
| 61 | 25 |  |  | 25 | 0 | 308 | my $game   = shift; | 
| 62 | 25 |  |  |  |  | 53 | my $size   = $game->{'size'}; | 
| 63 | 25 |  |  |  |  | 48 | my $result = $game->{'result'}; | 
| 64 | 25 |  |  |  |  | 525 | my $string = ""; | 
| 65 | 25 |  |  |  |  | 52 | foreach my $y (1..$size) { | 
| 66 | 227 |  |  |  |  | 302 | foreach my $x (1..$size) { | 
| 67 | 2135 |  |  |  |  | 3708 | $string .= dec_to_alpha($result->[$x][$y]); | 
| 68 |  |  |  |  |  |  | } | 
| 69 |  |  |  |  |  |  | } | 
| 70 | 25 |  |  |  |  | 229 | return $string; | 
| 71 |  |  |  |  |  |  | } | 
| 72 |  |  |  |  |  |  |  | 
| 73 |  |  |  |  |  |  | ################################################# | 
| 74 |  |  |  |  |  |  | # Solve the Sudoku (Recursive Function) | 
| 75 |  |  |  |  |  |  | ################################################# | 
| 76 |  |  |  |  |  |  | sub solve { | 
| 77 | 6936 |  |  | 6936 | 0 | 9167 | my $game   = shift; | 
| 78 | 6936 |  |  |  |  | 11493 | my $kube   = $game->{'kube'}; | 
| 79 | 6936 |  |  |  |  | 10553 | my $result = $game->{'result'}; | 
| 80 | 6936 |  |  |  |  | 8284 | while () { | 
| 81 | 18251 |  |  |  |  | 42144 | my $kube000 = $kube->[0][0][0]; | 
| 82 | 18251 |  |  |  |  | 51625 | get_value($game); | 
| 83 | 18251 |  |  |  |  | 73648 | get_value_square($game); | 
| 84 | 18251 | 100 |  |  |  | 59884 | return 1 if $result->[0][0] == ($game->{'size'} * $game->{'size'}); | 
| 85 | 18228 | 100 |  |  |  | 43401 | if ($kube000 == $kube->[0][0][0]) { | 
| 86 | 6913 | 100 |  |  |  | 252902 | return 0 unless $kube->[0][0][0]; | 
| 87 | 3494 |  |  |  |  | 9487 | my $options = get_options($game); | 
| 88 | 3494 | 50 |  |  |  | 5575 | if (scalar(@{$options})) { | 
|  | 3494 |  |  |  |  | 8880 |  | 
| 89 | 3494 |  |  |  |  | 3582 | foreach my $option (@{$options}) { | 
|  | 3494 |  |  |  |  | 6033 |  | 
| 90 | 6913 |  |  |  |  | 16899 | my $game2 = clone_data_struc($game); | 
| 91 | 6913 |  |  |  |  | 44015 | set_value($game2, $option->[0], $option->[1], $option->[2]); | 
| 92 | 6913 | 100 |  |  |  | 21382 | if (solve($game2)) { | 
| 93 | 149 |  |  |  |  | 297 | update_data_struc($game, $game2); | 
| 94 | 149 |  |  |  |  | 13777 | return 1; | 
| 95 |  |  |  |  |  |  | } | 
| 96 |  |  |  |  |  |  | } | 
| 97 |  |  |  |  |  |  | } | 
| 98 | 3345 |  |  |  |  | 374592 | return 0; | 
| 99 |  |  |  |  |  |  | } | 
| 100 |  |  |  |  |  |  | } | 
| 101 |  |  |  |  |  |  | } | 
| 102 |  |  |  |  |  |  |  | 
| 103 |  |  |  |  |  |  | ################################################# | 
| 104 |  |  |  |  |  |  | # Print the Sudoku Board with the Values | 
| 105 |  |  |  |  |  |  | ################################################# | 
| 106 |  |  |  |  |  |  | sub print_board { | 
| 107 | 0 |  |  | 0 | 0 | 0 | my $game   = shift; | 
| 108 | 0 |  |  |  |  | 0 | my $size   = $game->{'size'}; | 
| 109 | 0 |  |  |  |  | 0 | my $dim    = $game->{'dim'}; | 
| 110 | 0 |  |  |  |  | 0 | my $result = $game->{'result'}; | 
| 111 | 0 |  |  |  |  | 0 | foreach my $i (1..$size) { | 
| 112 | 0 | 0 |  |  |  | 0 | print '+'. join('', map { $_ % $dim ? '-' : '-+' } (1..$size))."\n" unless (($i-1) % $dim); | 
|  | 0 | 0 |  |  |  | 0 |  | 
| 113 | 0 | 0 |  |  |  | 0 | print '|'. join('', map { $_ % $dim ? dec_to_alpha($result->[$_][$i]) : dec_to_alpha($result->[$_][$i]).'|' } (1..$size))."\n"; | 
|  | 0 |  |  |  |  | 0 |  | 
| 114 |  |  |  |  |  |  | } | 
| 115 | 0 | 0 |  |  |  | 0 | print '+'. join('', map { $_ % $dim ? '-' : '-+' } (1..$size))."\n"; | 
|  | 0 |  |  |  |  | 0 |  | 
| 116 | 0 |  |  |  |  | 0 | return 1; | 
| 117 |  |  |  |  |  |  | } | 
| 118 |  |  |  |  |  |  |  | 
| 119 |  |  |  |  |  |  |  | 
| 120 |  |  |  |  |  |  |  | 
| 121 |  |  |  |  |  |  | ############################################################################### | 
| 122 |  |  |  |  |  |  | # Kubedoku Private Functions | 
| 123 |  |  |  |  |  |  | ############################################################################### | 
| 124 |  |  |  |  |  |  |  | 
| 125 |  |  |  |  |  |  |  | 
| 126 |  |  |  |  |  |  |  | 
| 127 |  |  |  |  |  |  | ################################################# | 
| 128 |  |  |  |  |  |  | # Get the Board Size | 
| 129 |  |  |  |  |  |  | ################################################# | 
| 130 |  |  |  |  |  |  | sub get_size { | 
| 131 | 23 |  |  | 23 | 0 | 31 | my $sudoku = shift; | 
| 132 | 23 |  |  |  |  | 41 | my $nums   = length($sudoku); | 
| 133 | 23 |  |  |  |  | 87 | my $size   = int(sqrt($nums)); | 
| 134 | 23 | 50 |  |  |  | 159 | if ($nums != ($size * $size)) { | 
| 135 | 0 |  |  |  |  | 0 | print STDERR "ERROR: Sudoku game doesn't have a right number of values !!!\n"; | 
| 136 | 0 |  |  |  |  | 0 | return 0; | 
| 137 |  |  |  |  |  |  | } | 
| 138 | 23 |  |  |  |  | 85 | return $size; | 
| 139 |  |  |  |  |  |  | } | 
| 140 |  |  |  |  |  |  |  | 
| 141 |  |  |  |  |  |  | ################################################# | 
| 142 |  |  |  |  |  |  | # Create the Game Data Structures | 
| 143 |  |  |  |  |  |  | ################################################# | 
| 144 |  |  |  |  |  |  | sub get_data_struc { | 
| 145 | 24 |  |  | 24 | 0 | 33 | my $game   = shift; | 
| 146 | 24 |  |  |  |  | 31 | my $size   = shift; | 
| 147 | 24 |  |  |  |  | 48 | my $dim    = int(sqrt($size)); | 
| 148 | 24 |  |  |  |  | 37 | my @matrix = (); | 
| 149 | 24 |  |  |  |  | 43 | my @kube   = (); | 
| 150 | 24 |  |  |  |  | 63 | foreach my $x (0..$size) { | 
| 151 | 242 |  |  |  |  | 331 | $matrix[$x] = (); | 
| 152 | 242 |  |  |  |  | 295 | $kube[$x] = (); | 
| 153 | 242 | 100 |  |  |  | 383 | my $valx = ($x ? 1 : $size); | 
| 154 | 242 |  |  |  |  | 303 | foreach my $y (0..$size) { | 
| 155 | 2514 |  |  |  |  | 3554 | $matrix[$x][$y] = 0; | 
| 156 | 2514 |  |  |  |  | 3389 | $kube[$x][$y] = (); | 
| 157 | 2514 | 100 |  |  |  | 3509 | my $valy = ($y ? 1 : $size); | 
| 158 | 2514 |  |  |  |  | 3279 | foreach my $z (0..$size) { | 
| 159 | 27038 | 100 |  |  |  | 37669 | my $valz = ($z ? 1 : $size); | 
| 160 | 27038 |  |  |  |  | 46213 | $kube[$x][$y][$z] = $valx * $valy * $valz; | 
| 161 |  |  |  |  |  |  | } | 
| 162 |  |  |  |  |  |  | } | 
| 163 |  |  |  |  |  |  | } | 
| 164 | 24 |  |  |  |  | 57 | my @square = (); | 
| 165 | 24 |  |  |  |  | 49 | foreach my $x (1..$dim) { | 
| 166 | 72 |  |  |  |  | 126 | $square[$x] = (); | 
| 167 | 72 |  |  |  |  | 106 | foreach my $y (1..$dim) { | 
| 168 | 218 |  |  |  |  | 305 | $square[$x][$y] = (); | 
| 169 | 218 |  |  |  |  | 274 | foreach my $z (1..$size) { | 
| 170 | 2054 |  |  |  |  | 3662 | $square[$x][$y][$z] = $size; | 
| 171 |  |  |  |  |  |  | } | 
| 172 |  |  |  |  |  |  | } | 
| 173 |  |  |  |  |  |  | } | 
| 174 | 24 |  |  |  |  | 78 | $game->{'size'}   = $size; | 
| 175 | 24 |  |  |  |  | 58 | $game->{'dim'}    = $dim; | 
| 176 | 24 |  |  |  |  | 68 | $game->{'result'} = \@matrix; | 
| 177 | 24 |  |  |  |  | 63 | $game->{'kube'}   = \@kube; | 
| 178 | 24 |  |  |  |  | 54 | $game->{'square'} = \@square; | 
| 179 | 24 |  |  |  |  | 83 | $game->{'level'}  = 0; | 
| 180 |  |  |  |  |  |  | } | 
| 181 |  |  |  |  |  |  |  | 
| 182 |  |  |  |  |  |  | ################################################# | 
| 183 |  |  |  |  |  |  | # Clone the Game Data Structures | 
| 184 |  |  |  |  |  |  | ################################################# | 
| 185 |  |  |  |  |  |  | sub clone_data_struc { | 
| 186 | 6914 |  |  | 6914 | 0 | 11613 | my $old    = shift; | 
| 187 | 6914 |  |  |  |  | 13316 | my $size   = $old->{'size'}; | 
| 188 | 6914 |  |  |  |  | 12185 | my $dim    = $old->{'dim'}; | 
| 189 | 6914 |  |  |  |  | 12185 | my $matrix = $old->{'result'}; | 
| 190 | 6914 |  |  |  |  | 10147 | my $kube   = $old->{'kube'}; | 
| 191 | 6914 |  |  |  |  | 12216 | my @matrix = (); | 
| 192 | 6914 |  |  |  |  | 9169 | my @kube   = (); | 
| 193 | 6914 |  |  |  |  | 13531 | foreach my $x (0..$size) { | 
| 194 | 69140 |  |  |  |  | 120867 | $matrix[$x] = (); | 
| 195 | 69140 |  |  |  |  | 89672 | $kube[$x] = (); | 
| 196 | 69140 |  |  |  |  | 92897 | foreach my $y (0..$size) { | 
| 197 | 691400 |  |  |  |  | 1334947 | $matrix[$x][$y] = $matrix->[$x][$y]; | 
| 198 | 691400 |  |  |  |  | 941753 | $kube[$x][$y] = (); | 
| 199 | 691400 |  |  |  |  | 901802 | foreach my $z (0..$size) { | 
| 200 | 6914000 |  |  |  |  | 13462977 | $kube[$x][$y][$z] = $kube->[$x][$y][$z]; | 
| 201 |  |  |  |  |  |  | } | 
| 202 |  |  |  |  |  |  | } | 
| 203 |  |  |  |  |  |  | } | 
| 204 | 6914 |  |  |  |  | 16650 | my $square = $old->{'square'}; | 
| 205 | 6914 |  |  |  |  | 13939 | my @square = (); | 
| 206 | 6914 |  |  |  |  | 13013 | foreach my $x (1..$dim) { | 
| 207 | 20742 |  |  |  |  | 28862 | $square[$x] = (); | 
| 208 | 20742 |  |  |  |  | 43709 | foreach my $y (1..$dim) { | 
| 209 | 62226 |  |  |  |  | 85657 | $square[$x][$y] = (); | 
| 210 | 62226 |  |  |  |  | 85322 | foreach my $z (1..$size) { | 
| 211 | 560034 |  |  |  |  | 1211244 | $square[$x][$y][$z] = $square->[$x][$y][$z]; | 
| 212 |  |  |  |  |  |  | } | 
| 213 |  |  |  |  |  |  | } | 
| 214 |  |  |  |  |  |  | } | 
| 215 | 6914 |  |  |  |  | 13560 | my $new = {}; | 
| 216 | 6914 |  |  |  |  | 22445 | $new->{'size'}   = $size; | 
| 217 | 6914 |  |  |  |  | 12622 | $new->{'dim'}    = $dim; | 
| 218 | 6914 |  |  |  |  | 17087 | $new->{'result'} = \@matrix; | 
| 219 | 6914 |  |  |  |  | 16392 | $new->{'kube'}   = \@kube; | 
| 220 | 6914 |  |  |  |  | 13316 | $new->{'square'} = \@square; | 
| 221 | 6914 |  |  |  |  | 17403 | $new->{'level'}  = $old->{'level'} + 1; | 
| 222 | 6914 |  |  |  |  | 22965 | return $new; | 
| 223 |  |  |  |  |  |  | } | 
| 224 |  |  |  |  |  |  |  | 
| 225 |  |  |  |  |  |  | ################################################# | 
| 226 |  |  |  |  |  |  | # Update the Game Data Structures | 
| 227 |  |  |  |  |  |  | ################################################# | 
| 228 |  |  |  |  |  |  | sub update_data_struc { | 
| 229 | 149 |  |  | 149 | 0 | 173 | my $self = shift; | 
| 230 | 149 |  |  |  |  | 156 | my $game = shift; | 
| 231 | 149 |  |  |  |  | 267 | $self->{'result'} = $game->{'result'}; | 
| 232 | 149 |  |  |  |  | 237 | $self->{'kube'}   = $game->{'kube'}; | 
| 233 | 149 |  |  |  |  | 217 | $self->{'square'} = $game->{'square'}; | 
| 234 | 149 |  |  |  |  | 2067 | $self->{'level'}  = $game->{'level'}; | 
| 235 |  |  |  |  |  |  | } | 
| 236 |  |  |  |  |  |  |  | 
| 237 |  |  |  |  |  |  | ################################################# | 
| 238 |  |  |  |  |  |  | # Set value and clean axis and square | 
| 239 |  |  |  |  |  |  | ################################################# | 
| 240 |  |  |  |  |  |  | sub set_value { | 
| 241 | 107412 |  |  | 107412 | 0 | 140311 | my $game = shift; | 
| 242 | 107412 |  |  |  |  | 112494 | my $x    = shift; | 
| 243 | 107412 |  |  |  |  | 105994 | my $y    = shift; | 
| 244 | 107412 |  |  |  |  | 104044 | my $z    = shift; | 
| 245 | 107412 |  |  |  |  | 155586 | my $size = $game->{'size'}; | 
| 246 | 107412 |  |  |  |  | 134015 | my $dim  = $game->{'dim'}; | 
| 247 | 107412 |  |  |  |  | 131444 | my $kube = $game->{'kube'}; | 
| 248 | 107412 |  |  |  |  | 188159 | set_result($game, $x, $y, $z); | 
| 249 | 107412 |  |  |  |  | 193108 | foreach my $i (1..$size) { | 
| 250 |  |  |  |  |  |  | # Clean "X" axis | 
| 251 | 968420 | 100 |  |  |  | 1999723 | if ($kube->[$i][$y][$z]) { | 
| 252 | 114945 |  |  |  |  | 151177 | $kube->[$i][$y][$z] = 0; | 
| 253 | 114945 |  |  |  |  | 214135 | set_counts($game, $i, $y, $z); | 
| 254 |  |  |  |  |  |  | } | 
| 255 |  |  |  |  |  |  | # Clean "Y" axis | 
| 256 | 968420 | 100 |  |  |  | 2033296 | if ($kube->[$x][$i][$z]) { | 
| 257 | 118188 |  |  |  |  | 156870 | $kube->[$x][$i][$z] = 0; | 
| 258 | 118188 |  |  |  |  | 189316 | set_counts($game, $x, $i, $z); | 
| 259 |  |  |  |  |  |  | } | 
| 260 |  |  |  |  |  |  | # Clean "Z" axis | 
| 261 | 968420 | 100 |  |  |  | 2304907 | if ($kube->[$x][$y][$i]) { | 
| 262 | 124235 |  |  |  |  | 196576 | $kube->[$x][$y][$i] = 0; | 
| 263 | 124235 |  |  |  |  | 212516 | set_counts($game, $x, $y, $i); | 
| 264 |  |  |  |  |  |  | } | 
| 265 |  |  |  |  |  |  | } | 
| 266 |  |  |  |  |  |  | # Clean Squares | 
| 267 | 107412 |  |  |  |  | 216372 | my $xs = (int(($x -1)/$dim)*$dim); | 
| 268 | 107412 |  |  |  |  | 152423 | my $ys = (int(($y -1)/$dim)*$dim); | 
| 269 | 107412 |  |  |  |  | 198707 | foreach my $i (($xs+1)..($xs+$dim)) { | 
| 270 | 322476 |  |  |  |  | 490919 | foreach my $j (($ys+1)..($ys+$dim)) { | 
| 271 | 968420 | 100 |  |  |  | 2492627 | if ($kube->[$i][$j][$z]) { | 
| 272 | 25174 |  |  |  |  | 33251 | $kube->[$i][$j][$z] = 0; | 
| 273 | 25174 |  |  |  |  | 53372 | set_counts($game, $i, $j, $z); | 
| 274 |  |  |  |  |  |  | } | 
| 275 |  |  |  |  |  |  | } | 
| 276 |  |  |  |  |  |  | } | 
| 277 |  |  |  |  |  |  | } | 
| 278 |  |  |  |  |  |  |  | 
| 279 |  |  |  |  |  |  | ################################################# | 
| 280 |  |  |  |  |  |  | # Update the Results Matrix | 
| 281 |  |  |  |  |  |  | ################################################# | 
| 282 |  |  |  |  |  |  | sub set_result { | 
| 283 | 107412 |  |  | 107412 | 0 | 123358 | my $game   = shift; | 
| 284 | 107412 |  |  |  |  | 122095 | my $x      = shift; | 
| 285 | 107412 |  |  |  |  | 109816 | my $y      = shift; | 
| 286 | 107412 |  |  |  |  | 150084 | my $z      = shift; | 
| 287 | 107412 |  |  |  |  | 172248 | my $result = $game->{'result'}; | 
| 288 | 107412 |  |  |  |  | 176794 | $result->[$x][$y] = $z; | 
| 289 | 107412 |  |  |  |  | 139216 | $result->[$x][0]++; | 
| 290 | 107412 |  |  |  |  | 143501 | $result->[0][$y]++; | 
| 291 | 107412 |  |  |  |  | 200649 | $result->[0][0]++; | 
| 292 |  |  |  |  |  |  | } | 
| 293 |  |  |  |  |  |  |  | 
| 294 |  |  |  |  |  |  | ################################################# | 
| 295 |  |  |  |  |  |  | # Update the Counters in the Matrix & Square | 
| 296 |  |  |  |  |  |  | ################################################# | 
| 297 |  |  |  |  |  |  | sub set_counts { | 
| 298 | 382542 |  |  | 382542 | 0 | 509849 | my $game   = shift; | 
| 299 | 382542 |  |  |  |  | 404485 | my $x      = shift; | 
| 300 | 382542 |  |  |  |  | 436766 | my $y      = shift; | 
| 301 | 382542 |  |  |  |  | 417544 | my $z      = shift; | 
| 302 | 382542 |  |  |  |  | 506367 | my $dim    = $game->{'dim'}; | 
| 303 | 382542 |  |  |  |  | 506598 | my $kube   = $game->{'kube'}; | 
| 304 | 382542 |  |  |  |  | 440001 | my $square = $game->{'square'}; | 
| 305 |  |  |  |  |  |  | # Planes | 
| 306 | 382542 |  |  |  |  | 533707 | $kube->[0][$y][$z]--; | 
| 307 | 382542 |  |  |  |  | 489959 | $kube->[$x][0][$z]--; | 
| 308 | 382542 |  |  |  |  | 489061 | $kube->[$x][$y][0]--; | 
| 309 | 382542 |  |  |  |  | 468860 | $kube->[0][0][0]--; | 
| 310 |  |  |  |  |  |  | # Squares | 
| 311 | 382542 |  |  |  |  | 638012 | $x = int(($x -1)/$dim)+1; | 
| 312 | 382542 |  |  |  |  | 486902 | $y = int(($y -1)/$dim)+1; | 
| 313 | 382542 |  |  |  |  | 860061 | $square->[$x][$y][$z]--; | 
| 314 |  |  |  |  |  |  | } | 
| 315 |  |  |  |  |  |  |  | 
| 316 |  |  |  |  |  |  | ################################################# | 
| 317 |  |  |  |  |  |  | # Get Values from the Cube Matrix | 
| 318 |  |  |  |  |  |  | ################################################# | 
| 319 |  |  |  |  |  |  | sub get_value { | 
| 320 | 18251 |  |  | 18251 | 0 | 22984 | my $game = shift; | 
| 321 | 18251 |  |  |  |  | 25403 | my $size = $game->{'size'}; | 
| 322 | 18251 |  |  |  |  | 29957 | my $kube = $game->{'kube'}; | 
| 323 | 18251 |  |  |  |  | 35526 | foreach my $i (0..$size) { | 
| 324 | 182561 |  |  |  |  | 275698 | foreach my $j (0..$size) { | 
| 325 |  |  |  |  |  |  | # Plane xy | 
| 326 | 1826537 | 100 |  |  |  | 3945458 | if ($kube->[$i][$j][0] == 1) { | 
| 327 | 25465 |  |  |  |  | 36159 | foreach my $k (1..$size) { | 
| 328 | 229520 | 100 |  |  |  | 518404 | if ($kube->[$i][$j][$k] == 1) { | 
| 329 | 25309 |  |  |  |  | 48774 | set_value($game, $i, $j, $k); | 
| 330 |  |  |  |  |  |  | } | 
| 331 |  |  |  |  |  |  | } | 
| 332 |  |  |  |  |  |  | } | 
| 333 |  |  |  |  |  |  | # Plane xz | 
| 334 | 1826537 | 100 |  |  |  | 3572099 | if ($kube->[$i][0][$j] == 1) { | 
| 335 | 26117 |  |  |  |  | 39292 | foreach my $k (1..$size) { | 
| 336 | 235258 | 100 |  |  |  | 502207 | if ($kube->[$i][$k][$j] == 1) { | 
| 337 | 25961 |  |  |  |  | 62638 | set_value($game, $i, $k, $j); | 
| 338 |  |  |  |  |  |  | } | 
| 339 |  |  |  |  |  |  | } | 
| 340 |  |  |  |  |  |  | } | 
| 341 |  |  |  |  |  |  | # Plane yz | 
| 342 | 1826537 | 100 |  |  |  | 4128604 | if ($kube->[0][$i][$j] == 1) { | 
| 343 | 26891 |  |  |  |  | 39943 | foreach my $k (1..$size) { | 
| 344 | 242312 | 100 |  |  |  | 583908 | if ($kube->[$k][$i][$j] == 1) { | 
| 345 | 26735 |  |  |  |  | 47391 | set_value($game, $k, $i, $j); | 
| 346 |  |  |  |  |  |  | } | 
| 347 |  |  |  |  |  |  | } | 
| 348 |  |  |  |  |  |  | } | 
| 349 |  |  |  |  |  |  | } | 
| 350 |  |  |  |  |  |  | } | 
| 351 |  |  |  |  |  |  | } | 
| 352 |  |  |  |  |  |  |  | 
| 353 |  |  |  |  |  |  | ################################################# | 
| 354 |  |  |  |  |  |  | # Get Values from the Squares | 
| 355 |  |  |  |  |  |  | ################################################# | 
| 356 |  |  |  |  |  |  | sub get_value_square { | 
| 357 | 18251 |  |  | 18251 | 0 | 22624 | my $game   = shift; | 
| 358 | 18251 |  |  |  |  | 28260 | my $dim    = $game->{'dim'}; | 
| 359 | 18251 |  |  |  |  | 22868 | my $size   = $game->{'size'}; | 
| 360 | 18251 |  |  |  |  | 24211 | my $kube   = $game->{'kube'}; | 
| 361 | 18251 |  |  |  |  | 26531 | my $square = $game->{'square'}; | 
| 362 | 18251 |  |  |  |  | 29190 | foreach my $x (1..$dim) { | 
| 363 | 54760 |  |  |  |  | 70380 | foreach my $y (1..$dim) { | 
| 364 | 164310 |  |  |  |  | 202293 | Z: foreach my $z (1..$size) { | 
| 365 | 1479666 | 100 |  |  |  | 3097525 | if ($square->[$x][$y][$z] == 1) { | 
| 366 | 21947 |  |  |  |  | 52468 | foreach my $i ((($x-1)*$dim+1)..($x*$dim)) { | 
| 367 | 41978 |  |  |  |  | 89440 | foreach my $j ((($y-1)*$dim+1)..($y*$dim)) { | 
| 368 | 102764 | 100 |  |  |  | 267576 | if ($kube->[$i][$j][$z] == 1) { | 
| 369 | 21947 |  |  |  |  | 45583 | set_value($game, $i, $j, $z); | 
| 370 | 21947 |  |  |  |  | 77344 | next Z; | 
| 371 |  |  |  |  |  |  | } | 
| 372 |  |  |  |  |  |  | } | 
| 373 |  |  |  |  |  |  | } | 
| 374 |  |  |  |  |  |  | } | 
| 375 |  |  |  |  |  |  | } | 
| 376 |  |  |  |  |  |  | } | 
| 377 |  |  |  |  |  |  | } | 
| 378 |  |  |  |  |  |  | } | 
| 379 |  |  |  |  |  |  |  | 
| 380 |  |  |  |  |  |  | ################################################# | 
| 381 |  |  |  |  |  |  | # Get Optional Values from the Line Counters | 
| 382 |  |  |  |  |  |  | ################################################# | 
| 383 |  |  |  |  |  |  | sub get_options { | 
| 384 | 3494 |  |  | 3494 | 0 | 5672 | my $game = shift; | 
| 385 | 3494 |  |  |  |  | 6125 | my $size = $game->{'size'}; | 
| 386 | 3494 |  |  |  |  | 12959 | my $kube = $game->{'kube'}; | 
| 387 | 3494 |  |  |  |  | 6454 | my $options = []; | 
| 388 | 3494 |  |  |  |  | 37531 | $options->[$_] = [] foreach (3..$size); | 
| 389 | 3494 |  |  |  |  | 7582 | foreach my $i (1..$size) { | 
| 390 | 5755 |  |  |  |  | 10684 | foreach my $j (1..$size) { | 
| 391 |  |  |  |  |  |  | # Plane xy | 
| 392 | 33321 | 100 |  |  |  | 72254 | if ($kube->[$i][$j][0]) { | 
| 393 | 4214 |  |  |  |  | 5999 | my $count = $kube->[$i][$j][0]; | 
| 394 | 4214 | 100 | 100 |  |  | 9384 | if (($count == 2) || (!@{$options->[$count]})) { | 
|  | 3368 |  |  |  |  | 12404 |  | 
| 395 | 1529 |  |  |  |  | 2471 | my $values = []; | 
| 396 | 1529 |  |  |  |  | 2767 | foreach my $k (1..$size) { | 
| 397 | 13761 | 100 |  |  |  | 28709 | if ($kube->[$i][$j][$k] == 1) { | 
| 398 | 4168 |  |  |  |  | 4651 | push(@{$values}, [$i, $j, $k]); | 
|  | 4168 |  |  |  |  | 11941 |  | 
| 399 |  |  |  |  |  |  | } | 
| 400 |  |  |  |  |  |  | } | 
| 401 | 1529 | 100 |  |  |  | 14841 | return $values if $count == 2; | 
| 402 | 683 |  |  |  |  | 863 | push(@{$options->[$count]}, $values); | 
|  | 683 |  |  |  |  | 1596 |  | 
| 403 |  |  |  |  |  |  | } | 
| 404 |  |  |  |  |  |  | } | 
| 405 |  |  |  |  |  |  | # Plane xz | 
| 406 | 32475 | 100 |  |  |  | 72785 | if ($kube->[$i][0][$j]) { | 
| 407 | 4139 |  |  |  |  | 6477 | my $count = $kube->[$i][0][$j]; | 
| 408 | 4139 | 100 | 100 |  |  | 9390 | if (($count == 2) || (!@{$options->[$count]})) { | 
|  | 3162 |  |  |  |  | 11937 |  | 
| 409 | 1680 |  |  |  |  | 2633 | my $values = []; | 
| 410 | 1680 |  |  |  |  | 2946 | foreach my $k (1..$size) { | 
| 411 | 15120 | 100 |  |  |  | 33285 | if ($kube->[$i][$k][$j] == 1) { | 
| 412 | 4394 |  |  |  |  | 3993 | push(@{$values}, [$i, $k, $j]); | 
|  | 4394 |  |  |  |  | 13274 |  | 
| 413 |  |  |  |  |  |  | } | 
| 414 |  |  |  |  |  |  | } | 
| 415 | 1680 | 100 |  |  |  | 8288 | return $values if $count == 2; | 
| 416 | 703 |  |  |  |  | 814 | push(@{$options->[$count]}, $values); | 
|  | 703 |  |  |  |  | 1708 |  | 
| 417 |  |  |  |  |  |  | } | 
| 418 |  |  |  |  |  |  | } | 
| 419 |  |  |  |  |  |  | # Plane yz | 
| 420 | 31498 | 100 |  |  |  | 71242 | if ($kube->[0][$i][$j]) { | 
| 421 | 8696 |  |  |  |  | 12641 | my $count = $kube->[0][$i][$j]; | 
| 422 | 8696 | 100 | 100 |  |  | 20731 | if (($count == 2) || (!@{$options->[$count]})) { | 
|  | 7025 |  |  |  |  | 27040 |  | 
| 423 | 4482 |  |  |  |  | 6352 | my $values = []; | 
| 424 | 4482 |  |  |  |  | 7269 | foreach my $k (1..$size) { | 
| 425 | 40338 | 100 |  |  |  | 88410 | if ($kube->[$k][$i][$j] == 1) { | 
| 426 | 14325 |  |  |  |  | 13506 | push(@{$values}, [$k, $i, $j]); | 
|  | 14325 |  |  |  |  | 39479 |  | 
| 427 |  |  |  |  |  |  | } | 
| 428 |  |  |  |  |  |  | } | 
| 429 | 4482 | 100 |  |  |  | 18189 | return $values if $count == 2; | 
| 430 | 2811 |  |  |  |  | 2944 | push(@{$options->[$count]}, $values); | 
|  | 2811 |  |  |  |  | 6883 |  | 
| 431 |  |  |  |  |  |  | } | 
| 432 |  |  |  |  |  |  | } | 
| 433 |  |  |  |  |  |  | } | 
| 434 |  |  |  |  |  |  | } | 
| 435 | 0 |  |  |  |  | 0 | foreach (3..$size) { | 
| 436 | 0 | 0 |  |  |  | 0 | return $options->[$_]->[0] if scalar($options->[$_]); | 
| 437 |  |  |  |  |  |  | } | 
| 438 | 0 |  |  |  |  | 0 | return []; | 
| 439 |  |  |  |  |  |  | } | 
| 440 |  |  |  |  |  |  |  | 
| 441 |  |  |  |  |  |  | ################################################# | 
| 442 |  |  |  |  |  |  | # Convert digits higher than 9 to letters | 
| 443 |  |  |  |  |  |  | ################################################# | 
| 444 |  |  |  |  |  |  | sub dec_to_alpha { | 
| 445 | 2135 |  |  | 2135 | 0 | 2124 | my $val = shift; | 
| 446 | 2135 | 100 |  |  |  | 6646 | return ($val > 9 ? chr($val + 87) : $val) if ($val); | 
|  |  | 100 |  |  |  |  |  | 
| 447 | 159 |  |  |  |  | 230 | return "."; | 
| 448 |  |  |  |  |  |  | } | 
| 449 |  |  |  |  |  |  |  | 
| 450 |  |  |  |  |  |  |  | 
| 451 |  |  |  |  |  |  |  | 
| 452 |  |  |  |  |  |  | ############################################################################### | 
| 453 |  |  |  |  |  |  | # Debug Functions | 
| 454 |  |  |  |  |  |  | ############################################################################### | 
| 455 |  |  |  |  |  |  | sub print_kube { | 
| 456 | 0 |  |  | 0 | 0 |  | my $game   = shift; | 
| 457 | 0 |  |  |  |  |  | my $size   = $game->{'size'}; | 
| 458 | 0 |  |  |  |  |  | my $dim    = $game->{'dim'}; | 
| 459 | 0 |  |  |  |  |  | my $kube   = $game->{'kube'}; | 
| 460 | 0 |  |  |  |  |  | print "-" x ($size*$size) ."\n"; | 
| 461 | 0 |  |  |  |  |  | foreach my $y (1..$size) { | 
| 462 | 0 |  |  |  |  |  | print "Y".$y; | 
| 463 | 0 |  |  |  |  |  | print join(" ", map { (" " x $dim).$_ .(" " x ($dim - 1)) } (1..$size)); | 
|  | 0 |  |  |  |  |  |  | 
| 464 | 0 |  |  |  |  |  | print "\n"; | 
| 465 | 0 |  |  |  |  |  | foreach my $z (1..$size) { | 
| 466 | 0 |  |  |  |  |  | print "Z".$z.(" " x $z); | 
| 467 | 0 |  |  |  |  |  | foreach my $x (1..$size) { | 
| 468 | 0 |  |  |  |  |  | print $kube->[$x][$y][$z].(" " x $size); | 
| 469 |  |  |  |  |  |  | } | 
| 470 | 0 |  |  |  |  |  | print "\n"; | 
| 471 |  |  |  |  |  |  | } | 
| 472 | 0 |  |  |  |  |  | print "\n"; | 
| 473 |  |  |  |  |  |  | } | 
| 474 | 0 |  |  |  |  |  | print "-" x ($size*$size) ."\n"; | 
| 475 |  |  |  |  |  |  | } | 
| 476 |  |  |  |  |  |  |  | 
| 477 |  |  |  |  |  |  | sub kube_to_string { | 
| 478 | 0 |  |  | 0 | 0 |  | my $game = shift; | 
| 479 | 0 |  |  |  |  |  | my $size = $game->{'size'}; | 
| 480 | 0 |  |  |  |  |  | my $kube = $game->{'kube'}; | 
| 481 | 0 |  |  |  |  |  | my $string = ""; | 
| 482 | 0 |  |  |  |  |  | foreach my $x (1..$size) { | 
| 483 | 0 |  |  |  |  |  | foreach my $y (1..$size) { | 
| 484 | 0 |  |  |  |  |  | foreach my $z (1..$size) { | 
| 485 | 0 |  |  |  |  |  | $string .= $kube->[$x][$y][$z]; | 
| 486 |  |  |  |  |  |  | } | 
| 487 |  |  |  |  |  |  | } | 
| 488 |  |  |  |  |  |  | } | 
| 489 | 0 |  |  |  |  |  | return $string; | 
| 490 |  |  |  |  |  |  | } | 
| 491 |  |  |  |  |  |  |  | 
| 492 |  |  |  |  |  |  | sub print_square { | 
| 493 | 0 |  |  | 0 | 0 |  | my $game   = shift; | 
| 494 | 0 |  |  |  |  |  | my $size   = $game->{'size'}; | 
| 495 | 0 |  |  |  |  |  | my $dim    = $game->{'dim'}; | 
| 496 | 0 |  |  |  |  |  | my $square = $game->{'square'}; | 
| 497 | 0 |  |  |  |  |  | print "-" x ($size*$size) ."\n"; | 
| 498 | 0 |  |  |  |  |  | foreach my $y (1..$dim) { | 
| 499 | 0 |  |  |  |  |  | print "Y".$y; | 
| 500 | 0 |  |  |  |  |  | print join(" ", map { (" " x $dim).$_ .(" " x ($dim - 1)) } (1..$dim)); | 
|  | 0 |  |  |  |  |  |  | 
| 501 | 0 |  |  |  |  |  | print "\n"; | 
| 502 | 0 |  |  |  |  |  | foreach my $z (1..$size) { | 
| 503 | 0 |  |  |  |  |  | print "Z".$z.(" " x $z); | 
| 504 | 0 |  |  |  |  |  | foreach my $x (1..$dim) { | 
| 505 | 0 |  |  |  |  |  | print $square->[$x][$y][$z].(" " x $size); | 
| 506 |  |  |  |  |  |  | } | 
| 507 | 0 |  |  |  |  |  | print "\n"; | 
| 508 |  |  |  |  |  |  | } | 
| 509 | 0 |  |  |  |  |  | print "\n"; | 
| 510 |  |  |  |  |  |  | } | 
| 511 | 0 |  |  |  |  |  | print "-" x ($size*$size) ."\n"; | 
| 512 |  |  |  |  |  |  | } | 
| 513 |  |  |  |  |  |  |  | 
| 514 |  |  |  |  |  |  |  | 
| 515 |  |  |  |  |  |  |  | 
| 516 |  |  |  |  |  |  | =head1 NAME | 
| 517 |  |  |  |  |  |  |  | 
| 518 |  |  |  |  |  |  | Games::Sudoku::Kubedoku - Sudoku Solver for any NxN puzzles | 
| 519 |  |  |  |  |  |  |  | 
| 520 |  |  |  |  |  |  | =head1 VERSION | 
| 521 |  |  |  |  |  |  |  | 
| 522 |  |  |  |  |  |  | Version 1.00 | 
| 523 |  |  |  |  |  |  |  | 
| 524 |  |  |  |  |  |  | =head1 SYNOPSIS | 
| 525 |  |  |  |  |  |  |  | 
| 526 |  |  |  |  |  |  | use Games::Sudoku::Kubedoku; | 
| 527 |  |  |  |  |  |  | my $sudoku = Games::Sudoku::Kubedoku->new('.4...7.35..5...8.7.78.65.9.9..2..3....364.7.9.6..3.2..5.....1...9.7.......235...4'); | 
| 528 |  |  |  |  |  |  | $sudoku->solve(); | 
| 529 |  |  |  |  |  |  | my $solution = $sudoku->get_game(); | 
| 530 |  |  |  |  |  |  | print "$solution\n"; | 
| 531 |  |  |  |  |  |  | $sudoku->print_board(); | 
| 532 |  |  |  |  |  |  |  | 
| 533 |  |  |  |  |  |  | Or: | 
| 534 |  |  |  |  |  |  |  | 
| 535 |  |  |  |  |  |  | use Games::Sudoku::Kubedoku; | 
| 536 |  |  |  |  |  |  | my $sudoku = Games::Sudoku::Kubedoku->new(); | 
| 537 |  |  |  |  |  |  | $sudoku->set_game('.4...7.35..5...8.7.78.65.9.9..2..3....364.7.9.6..3.2..5.....1...9.7.......235...4'); | 
| 538 |  |  |  |  |  |  | $sudoku->solve(); | 
| 539 |  |  |  |  |  |  | my $solution = $sudoku->get_game(); | 
| 540 |  |  |  |  |  |  | print "$solution\n"; | 
| 541 |  |  |  |  |  |  | $sudoku->print_board(); | 
| 542 |  |  |  |  |  |  |  | 
| 543 |  |  |  |  |  |  | =head1 DESCRIPTION | 
| 544 |  |  |  |  |  |  |  | 
| 545 |  |  |  |  |  |  | Kubedoku is a Sudoku Solver. It uses a cube(Kube) to solve the game. | 
| 546 |  |  |  |  |  |  | The rows, columns and values will become the axes (x,y,z). | 
| 547 |  |  |  |  |  |  | The kube has one property, once a value is set in the board, then all the axes (x,y,z) will become empties. | 
| 548 |  |  |  |  |  |  | The software will try to get all the unknown values checking axes with the sum of 1. | 
| 549 |  |  |  |  |  |  | If there is a sum higher than one, then It will execute recursive to get the right solution. | 
| 550 |  |  |  |  |  |  | The code is not the fastest but It is not too complex. | 
| 551 |  |  |  |  |  |  | The solver accept the written games with "." or "0" for the unknown values. | 
| 552 |  |  |  |  |  |  | The code support Sudokus with 4, 9, 16 or higher size. | 
| 553 |  |  |  |  |  |  | The games with more than 9 values has to use letters. | 
| 554 |  |  |  |  |  |  |  | 
| 555 |  |  |  |  |  |  | =head1 FUNCTIONS | 
| 556 |  |  |  |  |  |  |  | 
| 557 |  |  |  |  |  |  | =over 3 | 
| 558 |  |  |  |  |  |  |  | 
| 559 |  |  |  |  |  |  | =item * | 
| 560 |  |  |  |  |  |  |  | 
| 561 |  |  |  |  |  |  | B I | 
| 562 |  |  |  |  |  |  |  | 
| 563 |  |  |  |  |  |  | =item * | 
| 564 |  |  |  |  |  |  |  | 
| 565 |  |  |  |  |  |  | B I | 
| 566 |  |  |  |  |  |  |  | 
| 567 |  |  |  |  |  |  | =item * | 
| 568 |  |  |  |  |  |  |  | 
| 569 |  |  |  |  |  |  | B I | 
| 570 |  |  |  |  |  |  |  | 
| 571 |  |  |  |  |  |  | =item * | 
| 572 |  |  |  |  |  |  |  | 
| 573 |  |  |  |  |  |  | B I | 
| 574 |  |  |  |  |  |  |  | 
| 575 |  |  |  |  |  |  | =item * | 
| 576 |  |  |  |  |  |  |  | 
| 577 |  |  |  |  |  |  | B I | 
| 578 |  |  |  |  |  |  |  | 
| 579 |  |  |  |  |  |  | =back | 
| 580 |  |  |  |  |  |  |  | 
| 581 |  |  |  |  |  |  | =head1 EXAMPLES | 
| 582 |  |  |  |  |  |  |  | 
| 583 |  |  |  |  |  |  | use Games::Sudoku::Kubedoku; | 
| 584 |  |  |  |  |  |  | my $sudoku = Games::Sudoku::Kubedoku->new('1.34....432.21.3'); | 
| 585 |  |  |  |  |  |  | print $sudoku->get_game()."\n"; | 
| 586 |  |  |  |  |  |  | $sudoku->print_board(); | 
| 587 |  |  |  |  |  |  | $sudoku->solve(); | 
| 588 |  |  |  |  |  |  | print $sudoku->get_game()."\n"; | 
| 589 |  |  |  |  |  |  | $sudoku->print_board(); | 
| 590 |  |  |  |  |  |  |  | 
| 591 |  |  |  |  |  |  | 1.34....432.21.3 | 
| 592 |  |  |  |  |  |  | 1234341243212143 | 
| 593 |  |  |  |  |  |  |  | 
| 594 |  |  |  |  |  |  | +--+--+    +--+--+ | 
| 595 |  |  |  |  |  |  | |1.|34|    |12|34| | 
| 596 |  |  |  |  |  |  | |..|..|    |34|12| | 
| 597 |  |  |  |  |  |  | +--+--+    +--+--+ | 
| 598 |  |  |  |  |  |  | |43|2.|    |43|21| | 
| 599 |  |  |  |  |  |  | |21|.3|    |21|43| | 
| 600 |  |  |  |  |  |  | +--+--+    +--+--+ | 
| 601 |  |  |  |  |  |  |  | 
| 602 |  |  |  |  |  |  |  | 
| 603 |  |  |  |  |  |  | use Games::Sudoku::Kubedoku; | 
| 604 |  |  |  |  |  |  | my $sudoku = Games::Sudoku::Kubedoku->new('.4...7.35..5...8.7.78.65.9.9..2..3....364.7.9.6..3.2..5.....1...9.7.......235...4'); | 
| 605 |  |  |  |  |  |  | print $sudoku->get_game()."\n"; | 
| 606 |  |  |  |  |  |  | $sudoku->print_board(); | 
| 607 |  |  |  |  |  |  | $sudoku->solve(); | 
| 608 |  |  |  |  |  |  | print $sudoku->get_game()."\n"; | 
| 609 |  |  |  |  |  |  | $sudoku->print_board(); | 
| 610 |  |  |  |  |  |  |  | 
| 611 |  |  |  |  |  |  | .4...7.35..5...8.7.78.65.9.9..2..3....364.7.9.6..3.2..5.....1...9.7.......235...4 | 
| 612 |  |  |  |  |  |  | 149827635625493817378165492954278361283641759761539248537984126496712583812356974 | 
| 613 |  |  |  |  |  |  |  | 
| 614 |  |  |  |  |  |  | +---+---+---+    +---+---+---+ | 
| 615 |  |  |  |  |  |  | |.4.|..7|.35|    |149|827|635| | 
| 616 |  |  |  |  |  |  | |..5|...|8.7|    |625|493|817| | 
| 617 |  |  |  |  |  |  | |.78|.65|.9.|    |378|165|492| | 
| 618 |  |  |  |  |  |  | +---+---+---+    +---+---+---+ | 
| 619 |  |  |  |  |  |  | |9..|2..|3..|    |954|278|361| | 
| 620 |  |  |  |  |  |  | |..3|64.|7.9|    |283|641|759| | 
| 621 |  |  |  |  |  |  | |.6.|.3.|2..|    |761|539|248| | 
| 622 |  |  |  |  |  |  | +---+---+---+    +---+---+---+ | 
| 623 |  |  |  |  |  |  | |5..|...|1..|    |537|984|126| | 
| 624 |  |  |  |  |  |  | |.9.|7..|...|    |496|712|583| | 
| 625 |  |  |  |  |  |  | |..2|35.|..4|    |812|356|974| | 
| 626 |  |  |  |  |  |  | +---+---+---+    +---+---+---+ | 
| 627 |  |  |  |  |  |  |  | 
| 628 |  |  |  |  |  |  |  | 
| 629 |  |  |  |  |  |  | use Games::Sudoku::Kubedoku; | 
| 630 |  |  |  |  |  |  | my $sudoku = Games::Sudoku::Kubedoku->new('ad4...67..3b.c.....c9a.2.1..........5...g46..2.d....c.319...g.7.....a758..b..e....1...........9..g.d....e6f.c.1537b6.e2.5........e....1.7....5...f.7..c..b9........3e..4fg...6a.g4.8.b7...e3.9..4a....b6.e.f7...25f.......1.3..a.c3...g..a5.4d.b.6.128.3........'); | 
| 631 |  |  |  |  |  |  | print $sudoku->get_game()."\n"; | 
| 632 |  |  |  |  |  |  | $sudoku->print_board(); | 
| 633 |  |  |  |  |  |  | $sudoku->solve(); | 
| 634 |  |  |  |  |  |  | print $sudoku->get_game()."\n"; | 
| 635 |  |  |  |  |  |  | $sudoku->print_board(); | 
| 636 |  |  |  |  |  |  |  | 
| 637 |  |  |  |  |  |  | ad4...67..3b.c.....c9a.2.1..........5...g46..2.d....c.319...g.7.....a758..b..e....1...........9..g.d....e6f.c.1537b6.e2.5........e....1.7....5...f.7..c..b9........3e..4fg...6a.g4.8.b7...e3.9..4a....b6.e.f7...25f.......1.3..a.c3...g..a5.4d.b.6.128.3........ | 
| 638 |  |  |  |  |  |  | ad4f8g67253b9ce16bgc9ad2817e534f13795febg46ca28d58e2c4319fdagb76f9c4a75813bd6eg2e215g6fdc8a7b4938gadb349e6f2c71537b61e2c59g4daf8ce2a391g7d86f5b4df5762ca4b918g3eb193ed84fgc526a7g468fb75a2e319dc4a8gd5b63e2f71c925fb4c9ed71g386a9c3e71gf6a584d2b76d128a3bc49ef5g | 
| 639 |  |  |  |  |  |  |  | 
| 640 |  |  |  |  |  |  | +----+----+----+----+    +----+----+----+----+ | 
| 641 |  |  |  |  |  |  | |ad4.|..67|..3b|.c..|    |ad4f|8g67|253b|9ce1| | 
| 642 |  |  |  |  |  |  | |...c|9a.2|.1..|....|    |6bgc|9ad2|817e|534f| | 
| 643 |  |  |  |  |  |  | |....|5...|g46.|.2.d|    |1379|5feb|g46c|a28d| | 
| 644 |  |  |  |  |  |  | |....|c.31|9...|g.7.|    |58e2|c431|9fda|gb76| | 
| 645 |  |  |  |  |  |  | +----+----+----+----+    +----+----+----+----+ | 
| 646 |  |  |  |  |  |  | |....|a758|..b.|.e..|    |f9c4|a758|13bd|6eg2| | 
| 647 |  |  |  |  |  |  | |..1.|....|....|..9.|    |e215|g6fd|c8a7|b493| | 
| 648 |  |  |  |  |  |  | |.g.d|....|e6f.|c.15|    |8gad|b349|e6f2|c715| | 
| 649 |  |  |  |  |  |  | |37b6|.e2.|5...|....|    |37b6|1e2c|59g4|daf8| | 
| 650 |  |  |  |  |  |  | +----+----+----+----+    +----+----+----+----+ | 
| 651 |  |  |  |  |  |  | |.e..|..1.|7...|.5..|    |ce2a|391g|7d86|f5b4| | 
| 652 |  |  |  |  |  |  | |.f.7|..c.|.b9.|....|    |df57|62ca|4b91|8g3e| | 
| 653 |  |  |  |  |  |  | |...3|e..4|fg..|.6a.|    |b193|ed84|fgc5|26a7| | 
| 654 |  |  |  |  |  |  | |g4.8|.b7.|..e3|.9..|    |g468|fb75|a2e3|19dc| | 
| 655 |  |  |  |  |  |  | +----+----+----+----+    +----+----+----+----+ | 
| 656 |  |  |  |  |  |  | |4a..|..b6|.e.f|7...|    |4a8g|d5b6|3e2f|71c9| | 
| 657 |  |  |  |  |  |  | |25f.|....|..1.|3..a|    |25fb|4c9e|d71g|386a| | 
| 658 |  |  |  |  |  |  | |.c3.|..g.|.a5.|4d.b|    |9c3e|71gf|6a58|4d2b| | 
| 659 |  |  |  |  |  |  | |.6.1|28.3|....|....|    |76d1|28a3|bc49|ef5g| | 
| 660 |  |  |  |  |  |  | +----+----+----+----+    +----+----+----+----+ | 
| 661 |  |  |  |  |  |  |  | 
| 662 |  |  |  |  |  |  | =head1 AUTHOR | 
| 663 |  |  |  |  |  |  |  | 
| 664 |  |  |  |  |  |  | Sebastian Isaac Velasco, C<<  >>. | 
| 665 |  |  |  |  |  |  |  | 
| 666 |  |  |  |  |  |  | =head1 COPYRIGHT | 
| 667 |  |  |  |  |  |  |  | 
| 668 |  |  |  |  |  |  | Copyright 2013, Sebastian Isaac Velasco | 
| 669 |  |  |  |  |  |  |  | 
| 670 |  |  |  |  |  |  | This program is free software: you can redistribute it and/or modify | 
| 671 |  |  |  |  |  |  | it under the terms of the GNU General Public License as published by | 
| 672 |  |  |  |  |  |  | the Free Software Foundation, either version 3 of the License, or | 
| 673 |  |  |  |  |  |  | (at your option) any later version. | 
| 674 |  |  |  |  |  |  |  | 
| 675 |  |  |  |  |  |  | This program is distributed in the hope that it will be useful, | 
| 676 |  |  |  |  |  |  | but WITHOUT ANY WARRANTY; without even the implied warranty of | 
| 677 |  |  |  |  |  |  | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | 
| 678 |  |  |  |  |  |  | GNU General Public License for more details. | 
| 679 |  |  |  |  |  |  |  | 
| 680 |  |  |  |  |  |  | You should have received a copy of the GNU General Public License | 
| 681 |  |  |  |  |  |  | along with this program.  If not, see . | 
| 682 |  |  |  |  |  |  |  | 
| 683 |  |  |  |  |  |  | =head1 AVAILABILITY | 
| 684 |  |  |  |  |  |  |  | 
| 685 |  |  |  |  |  |  | The latest version of this library is likely to be available from CPAN as well as: | 
| 686 |  |  |  |  |  |  |  | 
| 687 |  |  |  |  |  |  | https://github.com/velascosebastian/kubedoku/perl | 
| 688 |  |  |  |  |  |  |  | 
| 689 |  |  |  |  |  |  | =cut | 
| 690 |  |  |  |  |  |  |  | 
| 691 |  |  |  |  |  |  | 1; |