#!/usr/bin/perl use v5.35.0; use Data::Dumper; use List::Util 'sum'; # Read garden as an array. First entry is width, # remainder are data. my @garden; while (<>) { push @garden, length unless @garden; push @garden, split //; } # Use flood-fills to assign each plot to a region. # # Line terminators become hidden regions where only # uninteresting \Weeds grow, neatly breaking what # would otherwise appear to be adjacency between # plots on left and right edges. my @regions; my %to_do; @to_do{(1 .. $#garden)} = (); while (my ($plot) = %to_do) { my ($area, $perimeter, @plots); my @queue = $plot; while (@queue) { my $plot = shift @queue; next unless exists $to_do{$plot}; delete $to_do{$plot}; $area++; $perimeter += 4; push @plots, $plot; for my $offset (-$garden[0], 1, $garden[0], -1) { my $neighbour = $plot + $offset; next unless 1 <= $neighbour <= $#garden; next unless $garden[$neighbour] eq $garden[$plot]; $perimeter--; push @queue, $neighbour; } } push @regions, [$area, $perimeter, \@plots] unless $garden[$plot] =~ /\W/; } #print Dumper \%regions; say sum map {my ($a, $p) = @$_; $a * $p} @regions;