]> www.fi.muni.cz Git - aoc.git/blob - 2022/46.pl
Day 25: examining the input
[aoc.git] / 2022 / 46.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 $moved = 1;
31 my $round = 0;
32 while (1) {
33         say "round ", ++$round;
34         my %prop;
35         my @prop;
36         for my $i (0 .. $#el) {
37                 my ($x, $y, $state) = @{ $el[$i] };
38                 my $prop;
39                 my $sum = -1;
40                 for my $x1 ($x-1 .. $x+1) {
41                         for my $y1 ($y-1 .. $y+1) {
42                                 $sum++ if $map{"$x1,$y1"};
43                         }
44                 }
45                 next if !$sum;
46                 DIR:
47                 for my $add (0 .. 3) {
48                         my $dir = ($add + $state) % 4;
49                         if ($dir == 0) {
50                                 for my $x1 ($x-1 .. $x+1) {
51                                         next DIR if occupied(\%map, $x1, $y-1);
52                                 }
53                                 $prop = [ $x, $y-1, 1, $i ];
54                                 last;
55                         } elsif ($dir == 1) {
56                                 for my $x1 ($x-1 .. $x+1) {
57                                         next DIR if occupied(\%map, $x1, $y+1);
58                                 }
59                                 $prop = [ $x, $y+1, 2, $i ];
60                                 last;
61                         } elsif ($dir == 2) {
62                                 for my $y1 ($y-1 .. $y+1) {
63                                         next DIR if occupied(\%map, $x-1, $y1);
64                                 }
65                                 $prop = [ $x-1, $y, 3, $i ];
66                                 last;
67                         } elsif ($dir == 3) {
68                                 for my $y1 ($y-1 .. $y+1) {
69                                         next DIR if occupied(\%map, $x+1, $y1);
70                                 }
71                                 $prop = [ $x+1, $y, 0, $i ];
72                                 last;
73                         }
74                 }
75                 if ($prop) {
76                         $prop[$i] = $prop;
77                         $prop{"$prop->[0],$prop->[1]"}++;
78                 }
79         }
80         last if !@prop;
81         $moved = 0;
82         for my $i (0 .. $#prop) {
83                 my $p = $prop[$i];
84                 next if !defined $p;
85                 my ($x1, $y1) = @$p;
86                 my ($x, $y) = @{ $el[$i] };
87                 if ($prop{"$x1,$y1"} != 1) {
88                         #say "$i not moving $x,$y -> $x1,$y1";
89                         next;
90                 }
91                 $moved++;
92                 #say "$i moved $x,$y -> $x1,$y1";
93                 undef $map{"$x,$y"};
94                 $map{"$x1,$y1"} = 1;
95                 $el[$i][0] = $x1;
96                 $el[$i][1] = $y1;
97         }
98         ($xmin, $xmax, $ymin, $ymax) = (undef, undef, undef, undef);
99         for my $e (@el) {
100                 my ($x, $y) = @$e;
101                 $xmin = $x if !defined $xmin || $xmin > $x;
102                 $ymin = $y if !defined $ymin || $ymin > $y;
103                 $xmax = $x if !defined $xmax || $xmax < $x;
104                 $ymax = $y if !defined $ymax || $ymax < $y;
105                 $e->[2]++;
106                 $e->[2] %= 4;
107         }
108         say "$xmin .. $xmax, $ymin .. $ymax";
109 }
110
111 say "result $xmin .. $xmax $ymin .. $ymax";
112 say $round;