]> www.fi.muni.cz Git - aoc2021.git/blob - 44.pl
f045ecf2b9fbf84ef57082e33ee3eddd7cea9358
[aoc2021.git] / 44.pl
1 #!/usr/bin/perl -w
2
3 use v5.16;
4
5 $; = ',';
6 my @cuboids;
7 while (<>) {
8         my $state = /^on / ? 1 : 0;
9         my ($xmin, $xmax, $ymin, $ymax, $zmin, $zmax) = /-?\d+/g;
10         ($xmin, $xmax) = ($xmax, $xmin) if $xmax < $xmin;
11         ($ymin, $ymax) = ($ymax, $ymin) if $ymax < $ymin;
12         ($zmin, $zmax) = ($zmax, $zmin) if $zmax < $zmin;
13         say "cuboid ", join(',', $xmin, $xmax, $ymin, $ymax, $zmin, $zmax, $state);
14         push @cuboids, [$xmin, $xmax, $ymin, $ymax, $zmin, $zmax, $state];
15 }
16
17 sub overlaps_int {
18         my ($min1, $max1, $min2, $max2) = @_;
19         return ($min1 >= $min2 && $min1 <= $max2)
20                 || ($max1 >= $min2 && $max1 <= $max2)
21                 || ($min1 <= $min2 && $max1 >= $max2)
22                 || ($min1 >= $min2 && $max1 <= $max2);
23 }
24
25 sub overlaps_axis {
26         my ($c1, $c2, $axis) = @_;
27         $axis *=2;
28         return overlaps_int($c1->[$axis], $c1->[$axis+1], $c2->[$axis], $c2->[$axis+1]);
29 }
30
31 my @nonint;
32 for my $c1 (@cuboids) {
33         my @nonint2;
34         say "=======";
35         while (@nonint) {
36                 my $c2 = shift @nonint;
37                         say "[", join(',', @$c1), "] and\n[", join(',', @$c2), "] test for overlap";
38                         if (($c1->[0] > $c2->[0] && $c1->[0] <= $c2->[1])
39                                 && overlaps_axis($c1, $c2, 1)
40                                 && overlaps_axis($c1, $c2, 2)) {
41                                 my @c = @$c2;
42                                 $c[1] = $c1->[0]-1;
43                                 push @nonint, [ @c ];
44                                 @c = @$c2;
45                                 $c[0] = $c1->[0];
46                                 push @nonint, [ @c ];
47                                 say "split at xmin=$c1->[0] :\n", join(',', @{ $nonint[-2] }), "\n", join(',', @{ $nonint[-1] }) ;
48                                 next;
49                         }
50                         if (($c1->[1] >= $c2->[0] && $c1->[1] < $c2->[1])
51                                 && overlaps_axis($c1, $c2, 1)
52                                 && overlaps_axis($c1, $c2, 2)) {
53                                 my @c = @$c2;
54                                 $c[1] = $c1->[1];
55                                 push @nonint, [ @c ];
56                                 @c = @$c2;
57                                 $c[0] = $c1->[1]+1;
58                                 push @nonint, [ @c ];
59                                 say "split at xmax=$c1->[1] :\n", join(',', @{ $nonint[-2] }), "\n", join(',', @{ $nonint[-1] }) ;
60                                 next;
61                         }
62                         if (($c1->[2] > $c2->[2] && $c1->[2] <= $c2->[3])
63                                 && overlaps_axis($c1, $c2, 0)
64                                 && overlaps_axis($c1, $c2, 2)) {
65                                 my @c = @$c2;
66                                 $c[3] = $c1->[2]-1;
67                                 push @nonint, [ @c ];
68                                 @c = @$c2;
69                                 $c[2] = $c1->[2];
70                                 push @nonint, [ @c ];
71                                 say "split at ymin=$c1->[2] :\n", join(',', @{ $nonint[-2] }), "\n", join(',', @{ $nonint[-1] }) ;
72                                 next;
73                         }
74                         if (($c1->[3] >= $c2->[2] && $c1->[3] < $c2->[3])
75                                 && overlaps_axis($c1, $c2, 0)
76                                 && overlaps_axis($c1, $c2, 2)) {
77                                 my @c = @$c2;
78                                 $c[3] = $c1->[3];
79                                 push @nonint, [ @c ];
80                                 @c = @$c2;
81                                 $c[2] = $c1->[3]+1;
82                                 push @nonint, [ @c ];
83                                 say "split at ymax=$c1->[3] :\n", join(',', @{ $nonint[-2] }), "\n", join(',', @{ $nonint[-1] }) ;
84                                 next;
85                         }
86                         if (($c1->[4] > $c2->[4] && $c1->[4] <= $c2->[5])
87                                 && overlaps_axis($c1, $c2, 0)
88                                 && overlaps_axis($c1, $c2, 1)) {
89                                 my @c = @$c2;
90                                 $c[5] = $c1->[4]-1;
91                                 push @nonint, [ @c ];
92                                 @c = @$c2;
93                                 $c[4] = $c1->[4];
94                                 push @nonint, [ @c ];
95                                 say "split at zmin=$c1->[4] :\n", join(',', @{ $nonint[-2] }), "\n", join(',', @{ $nonint[-1] }) ;
96                                 next;
97                         }
98                         if (($c1->[5] >= $c2->[4] && $c1->[5] < $c2->[5])
99                                 && overlaps_axis($c1, $c2, 0)
100                                 && overlaps_axis($c1, $c2, 1)) {
101                                 my @c = @$c2;
102                                 $c[5] = $c1->[5];
103                                 push @nonint, [ @c ];
104                                 @c = @$c2;
105                                 $c[4] = $c1->[5]+1;
106                                 push @nonint, [ @c ];
107                                 say "split at zmax=$c1->[5] :\n", join(',', @{ $nonint[-2] }), "\n", join(',', @{ $nonint[-1] }) ;
108                                 next;
109                         }
110                 if (($c1->[0] <= $c2->[0] && $c1->[1] >= $c2->[1])
111                         && ($c1->[2] <= $c2->[2] && $c1->[3] >= $c2->[3])
112                         && ($c1->[4] <= $c2->[4] && $c1->[5] >= $c2->[5])) {
113                         say "[", join(',', @$c1), "] fully encloses \n[", join(',', @$c2), "] = enclosed";
114                 } else {
115                         say "[", join(',', @$c1), "] and\n[", join(',', @$c2), "] do not overlap";
116                         push @nonint2, $c2;
117                 }
118         }
119         push @nonint2, $c1 if $c1->[6];
120         @nonint = @nonint2;
121
122 my $count;
123 for my $c1 (@nonint) {
124         my $size = ($c1->[1] - $c1->[0] + 1)
125                 * ($c1->[3] - $c1->[2] + 1)
126                 * ($c1->[5] - $c1->[4] + 1);
127         say "final: [", join(',', @$c1), "] = $size";
128         $count += $size;
129 }
130
131 say $count;
132
133 }