]> www.fi.muni.cz Git - aoc.git/blob - 2022/45.pl
Day 23
[aoc.git] / 2022 / 45.pl
1 #!/usr/bin/perl -w
2
3 use v5.36;
4 use strict;
5
6 my %map;
7 my $base = 1_000_000;
8 my @el;
9
10 my $y = $base;
11 while (<>) {
12         chomp;
13         my $x = $base;
14         for my $pt (split //) {
15                 if ($pt eq '#') {
16                         $map{"$x,$y"} = 1;
17                         push @el, [ $x, $y, 0 ];
18                 }
19                 $x++;
20         }
21         $y++;
22 }
23
24 sub occupied($map, $x, $y) {
25         return $map->{"$x,$y"};
26 }
27
28 my ($xmin, $xmax, $ymin, $ymax);
29
30 my $round = 0;
31 while ($round < 10) {
32         say "round ", ++$round;
33         my %prop;
34         my @prop;
35         for my $i (0 .. $#el) {
36                 my ($x, $y, $state) = @{ $el[$i] };
37                 my $prop;
38                 my $sum = -1;
39                 for my $x1 ($x-1 .. $x+1) {
40                         for my $y1 ($y-1 .. $y+1) {
41                                 $sum++ if $map{"$x1,$y1"};
42                         }
43                 }
44                 next if !$sum;
45                 DIR:
46                 for my $add (0 .. 3) {
47                         my $dir = ($add + $state) % 4;
48                         if ($dir == 0) {
49                                 for my $x1 ($x-1 .. $x+1) {
50                                         next DIR if occupied(\%map, $x1, $y-1);
51                                 }
52                                 $prop = [ $x, $y-1, 1, $i ];
53                                 last;
54                         } elsif ($dir == 1) {
55                                 for my $x1 ($x-1 .. $x+1) {
56                                         next DIR if occupied(\%map, $x1, $y+1);
57                                 }
58                                 $prop = [ $x, $y+1, 2, $i ];
59                                 last;
60                         } elsif ($dir == 2) {
61                                 for my $y1 ($y-1 .. $y+1) {
62                                         next DIR if occupied(\%map, $x-1, $y1);
63                                 }
64                                 $prop = [ $x-1, $y, 3, $i ];
65                                 last;
66                         } elsif ($dir == 3) {
67                                 for my $y1 ($y-1 .. $y+1) {
68                                         next DIR if occupied(\%map, $x+1, $y1);
69                                 }
70                                 $prop = [ $x+1, $y, 0, $i ];
71                                 last;
72                         }
73                 }
74                 if ($prop) {
75                         $prop[$i] = $prop;
76                         $prop{"$prop->[0],$prop->[1]"}++;
77                 }
78         }
79         last if !@prop;
80         for my $i (0 .. $#prop) {
81                 my $p = $prop[$i];
82                 next if !defined $p;
83                 my ($x1, $y1) = @$p;
84                 my ($x, $y) = @{ $el[$i] };
85                 if ($prop{"$x1,$y1"} != 1) {
86                         next;
87                 }
88                 undef $map{"$x,$y"};
89                 $map{"$x1,$y1"} = 1;
90                 $el[$i][0] = $x1;
91                 $el[$i][1] = $y1;
92         }
93         ($xmin, $xmax, $ymin, $ymax) = (undef, undef, undef, undef);
94         for my $e (@el) {
95                 my ($x, $y) = @$e;
96                 $xmin = $x if !defined $xmin || $xmin > $x;
97                 $ymin = $y if !defined $ymin || $ymin > $y;
98                 $xmax = $x if !defined $xmax || $xmax < $x;
99                 $ymax = $y if !defined $ymax || $ymax < $y;
100                 $e->[2]++;
101                 $e->[2] %= 4;
102         }
103 }
104
105 say (($xmax - $xmin + 1) * ($ymax - $ymin + 1) - @el);
106