#!/usr/bin/perl use strict; chomp( my @data = ); $_ = [ split // ] for @data; do { print_map(\@data); print "=====\n"; } while (remove_vert_seam(\@data)); sub remove_vert_seam { my $data = shift; my $seam; my $rows = $#$data; my $cols = $#{ $data[0] }; for my $j (0 .. $cols) { $seam->[0][$j] = 0 if $data->[0][$j] eq "."; } # there is a seam from the top row to ($i,$j) # only if (i,j) has a "." and there is a seam from # the top row to any of (i-1,j-1), (i-1,j), (i-1,j+1) # if there is a seam, remember its predecessor so we # can trace it back. for my $i (1 .. $rows) { for my $j (0 .. $cols) { if ($data->[$i][$j] eq ".") { $seam->[$i][$j] = $j-1 if $j-1 >= 0 and defined $seam->[$i-1][$j-1]; $seam->[$i][$j] = $j if defined $seam->[$i-1][$j]; $seam->[$i][$j] = $j+1 if $j+1 <= $cols and defined $seam->[$i-1][$j+1]; } } } # if there is a seam to the bottom row, trace it back # to the top and remove all of the cells that are visited for my $j (0 .. $cols) { if (defined $seam->[$rows][$j]) { my $i = $rows; while ($i >= 0) { splice @{ $data->[$i] }, $j, 1; ($i,$j) = ($i-1, $seam->[$i][$j]); } return 1; } } return 0; } sub print_map { my $data = shift; for (@$data) { print join("", @$_), $/; } } __DATA__ XX... X.... ..... ....X ...XX