--- /dev/null
+#!/usr/bin/perl -w
+
+use v5.40;
+
+my @map = map { chomp; [ split // ] } <>;
+my $xmax = $#{ $map[0] };
+my $ymax = $#map;
+
+my %seen;
+my $sum;
+for my $y (0 .. $ymax) {
+ for my $x (0 .. $xmax) {
+ $sum += walk($x, $y) if !$seen{"$x,$y"};
+ }
+}
+say $sum;
+
+sub walk {
+ my ($x0, $y0) = (@_);
+
+ my $m = $map[$y0][$x0];
+ my ($area, $price);
+
+ my @q = [$x0, $y0];
+ while (my $qe = shift @q) {
+ my ($x, $y) = @$qe;
+ next if $seen{"$x,$y"}++;
+
+ $area++;
+
+ for my ($dx, $dy) (
+ -1, 0,
+ 1, 0,
+ 0, -1,
+ 0, 1,
+ ) {
+ my ($nx, $ny) = ($x+$dx, $y+$dy);
+ if ($nx < 0 || $nx > $xmax
+ || $ny < 0 || $ny > $ymax) {
+ $price++;
+ } elsif ($map[$ny][$nx] ne $m) {
+ $price++;
+ } else {
+ push @q, [$nx, $ny];
+ }
+ }
+ }
+ # say "$m at $_[0] $_[1] area $area price $price";
+ return $area * $price;
+}
--- /dev/null
+#!/usr/bin/perl -w
+
+use v5.40;
+
+my @map = map { chomp; [ split // ] } <>;
+my $xmax = $#{ $map[0] };
+my $ymax = $#map;
+
+my %seen;
+my $sum;
+for my $y (0 .. $ymax) {
+ for my $x (0 .. $xmax) {
+ $sum += walk($x, $y) if !$seen{"$x,$y"};
+ }
+}
+say $sum;
+
+sub walk {
+ my ($x0, $y0) = (@_);
+
+ my $m = $map[$y0][$x0];
+ my ($area, $price);
+
+ my (%sides, @sides);
+ my @q = [$x0, $y0];
+ while (my $qe = shift @q) {
+ my ($x, $y) = @$qe;
+ next if $seen{"$x,$y"}++;
+
+ $area++;
+
+ for my ($dx, $dy, $dir) (
+ -1, 0, 'L',
+ 1, 0, 'R',
+ 0, -1, 'U',
+ 0, 1, 'D',
+ ) {
+ my ($nx, $ny) = ($x+$dx, $y+$dy);
+ if ($nx < 0 || $nx > $xmax
+ || $ny < 0 || $ny > $ymax
+ || $map[$ny][$nx] ne $m) {
+ $sides{"$nx,$ny,$dir"}++;
+ push @sides, [$nx, $ny, $dir];
+ } else {
+ push @q, [$nx, $ny];
+ }
+ }
+ }
+
+ my %sseen;
+ for my $side (@sides) {
+ my ($x, $y, $dir) = @$side;
+ next if $sseen{"$x,$y,$dir"}++;
+
+ if ($dir =~ /[UD]/) {
+ my $x1 = $x;
+ while ($sides{"$x1,$y,$dir"}) {
+ $sseen{"$x1,$y,$dir"}++;
+ $x1++;
+ }
+ $x1 = $x-1;
+ while ($sides{"$x1,$y,$dir"}) {
+ $sseen{"$x1,$y,$dir"}++;
+ $x1--;
+ }
+ } else {
+ my $y1 = $y;
+ while ($sides{"$x,$y1,$dir"}) {
+ $sseen{"$x,$y1,$dir"}++;
+ $y1++;
+ }
+ $y1 = $y-1;
+ while ($sides{"$x,$y1,$dir"}) {
+ $sseen{"$x,$y1,$dir"}++;
+ $y1--;
+ }
+ }
+ $price++;
+ }
+
+ return $area * $price;
+}