Algorithm-X-DLX
view release on metacpan or search on metacpan
lib/Algorithm/X/ExactCoverProblem.pm view on Meta::CPAN
package Algorithm::X::ExactCoverProblem;
use strict;
use warnings;
require 5.06.0;
use Carp;
# Constructor with width and secondary_columns
sub new {
my ($class, $width, $rows_ref, $secondary_columns) = @_;
$width = 0 unless defined $width;
$secondary_columns = 0 unless defined $secondary_columns;
my $self = bless {
rows_ => [],
width_ => $width,
secondary_columns_ => $secondary_columns,
}, $class;
if ($secondary_columns > $width) {
croak("secondary_columns > width");
}
if (defined $rows_ref) {
foreach my $row (@$rows_ref) {
$self->add_row($row);
}
}
return $self;
}
# Factory method for a dense ExactCoverProblem (binary matrix)
sub dense {
my ($class, $bit_rows_ref, $secondary_columns) = @_;
if (!@$bit_rows_ref) {
return $class->new(0, undef, $secondary_columns);
}
my $width = scalar @{$bit_rows_ref->[0]};
my $problem = $class->new($width, undef, $secondary_columns);
foreach my $bits (@$bit_rows_ref) {
if (scalar @$bits != $width) {
croak("rows have different lengths");
}
my @row;
for (my $i = 0; $i < @$bits; ++$i) {
if ($bits->[$i] != 0 && $bits->[$i] != 1) {
croak("dense matrix must contain only 0s and 1s");
}
push @row, $i if $bits->[$i];
}
$problem->add_row(\@row);
}
return $problem;
}
# Accessors
sub width {
my ($self) = @_;
return $self->{width_};
}
sub rows {
my ($self) = @_;
return $self->{rows_};
}
sub secondary_columns {
my ($self) = @_;
( run in 1.346 second using v1.01-cache-2.11-cpan-5735350b133 )