Question 4: Behind the scenes
use Math::PlanePath::HilbertCurve;
use Data::Dumper;
my $input_file = 'path-bitmap.xpm';
my $line_buffer = '';
my $pic = read_xpm_bitmap($input_file);
output_path($pic);
exit;
sub read_xpm_bitmap {
my($file) = @_;
open my $fh, '<', $file;
scalar(<$fh>) foreach 1..5;
my @rows;
while(<$fh>) {
my @pixels = m{([ \.])}g;
push @rows, \@pixels if @pixels;
}
return \@rows;
}
sub output_path {
my($pic) = @_;
my $rows = scalar(@$pic);
my $cols = scalar(@{ $pic->[0] });
my $last = $rows * $cols - 1;
my $path = Math::PlanePath::HilbertCurve->new;
my($r, $c, $new_r, $new_c, $pixel);
foreach my $i (0 .. $last) {
($new_r, $new_c) = $path->n_to_xy($i);
if($i > 0) {
if($new_r < $r) {
output('N');
}
elsif($new_r > $r) {
output('S');
}
elsif($new_c > $c) {
output('E');
}
else {
output('W');
}
}
$r = $new_r;
$c = $new_c;
$pixel = $pic->[$r]->[$c] // die "No pixel at row $r column $c";
output('*') if $pixel ne ' ';
}
say $line_buffer;
}
sub output {
my($char) = @_;
if(length($line_buffer) >= 78) {
say $line_buffer;
$line_buffer = '';
}
$line_buffer .= $char;
}