Algorithm-X-DLX
view release on metacpan or search on metacpan
examples/sudoku/SudokuFormat.pm view on Meta::CPAN
sub is_cell {
my ($c, $self) = @_;
return is_empty($c) || index($self->{labels}, $c) != -1;
}
sub value {
my ($c, $self) = @_;
my $pos = index($self->{labels}, $c);
return ($pos == -1) ? 0 : ($pos + 1);
}
sub label {
my ($i, $self) = @_;
croak "Index out of bounds" if ($i > length($self->{labels}));
return ($i == 0) ? '.' : substr($self->{labels}, $i - 1, 1);
}
sub labels {
my ($self) = @_;
return $self->{labels};
}
sub get_values {
my ($str, $self) = @_;
my @labels = choose_labels($str);
my @values;
foreach my $c (split //, $str) {
my $pos = index(join('', @labels), $c);
if ($pos != -1) {
push @values, ($pos + 1);
} elsif (is_empty($c)) {
push @values, 0;
}
}
return \@values;
}
sub to_string {
my ($self, @values) = @_;
my $value_size = scalar(@values);
my $type_size = $self->type->size();
croak "to_string(): wrong number of values ($value_size vs. $type_size)" if $value_size != $type_size;
my @result_chars = split //, $self->{template};
my $j = 0;
for (my $i=0; $i < @result_chars; ++$i) {
if (is_cell($result_chars[$i], $self)) {
croak "Logic error" if (@values <= $j);
$result_chars[$i] = label($values[$j], $self);
$j++;
}
}
croak "Logic error" if (@values != $j);
return join('', @result_chars);
}
sub type {
return shift->{type};
}
sub is_empty {
my $c = shift;
return $c eq '.' || $c eq '0';
}
sub is_valid_label {
return index(valid_labels(), shift) != -1;
}
sub is_valid_cell {
my $c = shift;
return is_valid_label($c) || is_empty($c);
}
sub valid_labels {
return '123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
}
sub choose_labels {
my ($str) = @_;
my $size = 0;
foreach my $c (split //, $str) {
if (is_valid_cell($c)) {
$size++;
}
}
my $n = 0;
while (($n + 1) * ($n + 1) <= $size) {
$n++;
}
if ($n * $n != $size) {
croak ":(";
}
return choose_labels_n($str, $n);
}
sub choose_labels_n {
my ($str, $n) = @_;
my %used;
foreach my $c (split //, $str) {
if (is_valid_label($c)) {
$used{$c}++;
}
}
if (scalar(keys %used) > $n) {
( run in 0.541 second using v1.01-cache-2.11-cpan-c966e8aa7e8 )