--- /dev/null
+#!/usr/bin/perl -w
+
+use v5.40;
+
+my @map;
+my ($x, $y);
+while (<>) {
+ chomp;
+ if (/S/g) {
+ $x = pos()-1;
+ $y = $.-1;
+ }
+ push @map, [ split // ];
+}
+my $xmax = $#{$map[0]};
+my $ymax = $#map;
+
+sub walk {
+ my ($x, $y) = @_;
+
+ my @q = [0, $x, $y];
+ my %seen;
+ while (@q) {
+ my ($cost, $x, $y) = @{ shift @q };
+ next if $seen{"$x,$y"}++;
+ if ($map[$y][$x] eq 'E') {
+ return $cost;
+ }
+ for my ($dx, $dy) (-1, 0, 1, 0, 0, -1, 0, 1) {
+ my ($nx, $ny) = ($x+$dx, $y+$dy);
+ next if $map[$ny][$nx] eq '#';
+ push @q, [$cost+1, $nx, $ny];
+ }
+ }
+ return undef;
+}
+
+my $base = walk($x, $y);
+my $count = 0;
+for my $y1 (1 .. $#map -1) {
+ for my $x1 (1 .. $#{ $map[0] } -1) {
+ next if $map[$y1][$x1] ne '#';
+ $map[$y1][$x1] = '.';
+ my $s = walk($x, $y);
+ $count++ if $base - $s >= 100;
+ $map[$y1][$x1] = '#';
+ }
+}
+say $count;
--- /dev/null
+#!/usr/bin/perl -w
+
+use v5.40;
+
+my @map;
+my ($x, $y);
+while (<>) {
+ chomp;
+ if (/E/g) {
+ $x = pos()-1;
+ $y = $.-1;
+ }
+
+ push @map, [ split // ];
+}
+my $xmax = $#{ $map[0] };
+my $ymax = $#map;
+
+my %dist;
+my @q = [0, $x, $y];
+while (@q) {
+ my ($cost, $x, $y) = @{ shift @q };
+ next if defined $dist{"$x,$y"};
+ $dist{"$x,$y"} = $cost;
+ for my ($dx, $dy) (-1, 0, 1, 0, 0, -1, 0, 1) {
+ my ($nx, $ny) = ($x+$dx, $y+$dy);
+ next if $map[$ny][$nx] eq '#';
+ push @q, [$cost+1, $nx, $ny];
+ }
+}
+
+my $base = $dist{"$x,$y"};
+my $count = 0;
+my $lim = 20;
+my $min = 100;
+for my $y1 (1 .. $ymax -1) {
+ for my $x1 (1 .. $xmax-1) {
+ next if !exists $dist{"$x1,$y1"};
+ for my $dx (-$lim .. $lim) {
+ for my $dy (-$lim+abs($dx) .. $lim-abs($dx)) {
+ my ($nx, $ny) = ($x1+$dx, $y1+$dy);
+ next if $nx < 0 || $nx > $xmax
+ || $ny < 0 || $ny > $ymax
+ || $map[$ny][$nx] eq '#'
+ || !exists $dist{"$nx,$ny"};
+ my $saved =
+ + $dist{"$x1,$y1"} - $dist{"$nx,$ny"}
+ - (abs($dx)+abs($dy));
+ $count++ if $saved >= $min;
+ }
+ }
+ }
+}
+say $count;