]> www.fi.muni.cz Git - aoc2021.git/commitdiff
Day 22: copy&paste in 3D, and don't make a mistake
authorJan "Yenya" Kasprzak <kas@fi.muni.cz>
Wed, 22 Dec 2021 06:53:20 +0000 (07:53 +0100)
committerJan "Yenya" Kasprzak <kas@fi.muni.cz>
Wed, 22 Dec 2021 06:53:20 +0000 (07:53 +0100)
43.pl [new file with mode: 0755]
44.pl [new file with mode: 0755]

diff --git a/43.pl b/43.pl
new file mode 100755 (executable)
index 0000000..c7c2cc1
--- /dev/null
+++ b/43.pl
@@ -0,0 +1,38 @@
+#!/usr/bin/perl -w
+
+use v5.16;
+
+$; = ',';
+my %cubes;
+while (<>) {
+       my $state = /^on / ? 1 : 0;
+       my ($xmin, $xmax, $ymin, $ymax, $zmin, $zmax) = /-?\d+/g;
+       ($xmin, $xmax) = ($xmax, $xmin) if $xmax < $xmin;
+       ($ymin, $ymax) = ($ymax, $ymin) if $ymax < $ymin;
+       ($zmin, $zmax) = ($zmax, $zmin) if $zmax < $zmin;
+       say "cuboid ", join(',', $state, $xmin, $xmax, $ymin, $ymax, $zmin, $zmax);
+       next if ($xmax < -50 || $ymax < -50 || $zmax < -50);
+       next if ($xmin > 50 || $ymin > 50 || $zmin > 50);
+       $xmin = -50 if ($xmin < -50);
+       $ymin = -50 if ($ymin < -50);
+       $zmin = -50 if ($zmin < -50);
+       $xmax = 50 if $xmax > 50;
+       $ymax = 50 if $zmax > 50;
+       $zmax = 50 if $zmax > 50;
+       for my $x ($xmin .. $xmax) {
+       for my $y ($ymin .. $ymax) {
+       for my $z ($zmin .. $zmax) {
+               $cubes{$x,$y,$z} = $state;
+               say "$x,$y,$z => $state";
+       } } }
+}
+
+my $count;
+for my $x (-50 .. 50) {
+for my $y (-50 .. 50) {
+for my $z (-50 .. 50) {
+       $count++ if $cubes{$x,$y,$z};
+} } }
+
+say $count;
+
diff --git a/44.pl b/44.pl
new file mode 100755 (executable)
index 0000000..f045ecf
--- /dev/null
+++ b/44.pl
@@ -0,0 +1,133 @@
+#!/usr/bin/perl -w
+
+use v5.16;
+
+$; = ',';
+my @cuboids;
+while (<>) {
+       my $state = /^on / ? 1 : 0;
+       my ($xmin, $xmax, $ymin, $ymax, $zmin, $zmax) = /-?\d+/g;
+       ($xmin, $xmax) = ($xmax, $xmin) if $xmax < $xmin;
+       ($ymin, $ymax) = ($ymax, $ymin) if $ymax < $ymin;
+       ($zmin, $zmax) = ($zmax, $zmin) if $zmax < $zmin;
+       say "cuboid ", join(',', $xmin, $xmax, $ymin, $ymax, $zmin, $zmax, $state);
+       push @cuboids, [$xmin, $xmax, $ymin, $ymax, $zmin, $zmax, $state];
+}
+
+sub overlaps_int {
+       my ($min1, $max1, $min2, $max2) = @_;
+       return ($min1 >= $min2 && $min1 <= $max2)
+               || ($max1 >= $min2 && $max1 <= $max2)
+               || ($min1 <= $min2 && $max1 >= $max2)
+               || ($min1 >= $min2 && $max1 <= $max2);
+}
+
+sub overlaps_axis {
+       my ($c1, $c2, $axis) = @_;
+       $axis *=2;
+       return overlaps_int($c1->[$axis], $c1->[$axis+1], $c2->[$axis], $c2->[$axis+1]);
+}
+
+my @nonint;
+for my $c1 (@cuboids) {
+       my @nonint2;
+       say "=======";
+       while (@nonint) {
+               my $c2 = shift @nonint;
+                       say "[", join(',', @$c1), "] and\n[", join(',', @$c2), "] test for overlap";
+                       if (($c1->[0] > $c2->[0] && $c1->[0] <= $c2->[1])
+                               && overlaps_axis($c1, $c2, 1)
+                               && overlaps_axis($c1, $c2, 2)) {
+                               my @c = @$c2;
+                               $c[1] = $c1->[0]-1;
+                               push @nonint, [ @c ];
+                               @c = @$c2;
+                               $c[0] = $c1->[0];
+                               push @nonint, [ @c ];
+                               say "split at xmin=$c1->[0] :\n", join(',', @{ $nonint[-2] }), "\n", join(',', @{ $nonint[-1] }) ;
+                               next;
+                       }
+                       if (($c1->[1] >= $c2->[0] && $c1->[1] < $c2->[1])
+                               && overlaps_axis($c1, $c2, 1)
+                               && overlaps_axis($c1, $c2, 2)) {
+                               my @c = @$c2;
+                               $c[1] = $c1->[1];
+                               push @nonint, [ @c ];
+                               @c = @$c2;
+                               $c[0] = $c1->[1]+1;
+                               push @nonint, [ @c ];
+                               say "split at xmax=$c1->[1] :\n", join(',', @{ $nonint[-2] }), "\n", join(',', @{ $nonint[-1] }) ;
+                               next;
+                       }
+                       if (($c1->[2] > $c2->[2] && $c1->[2] <= $c2->[3])
+                               && overlaps_axis($c1, $c2, 0)
+                               && overlaps_axis($c1, $c2, 2)) {
+                               my @c = @$c2;
+                               $c[3] = $c1->[2]-1;
+                               push @nonint, [ @c ];
+                               @c = @$c2;
+                               $c[2] = $c1->[2];
+                               push @nonint, [ @c ];
+                               say "split at ymin=$c1->[2] :\n", join(',', @{ $nonint[-2] }), "\n", join(',', @{ $nonint[-1] }) ;
+                               next;
+                       }
+                       if (($c1->[3] >= $c2->[2] && $c1->[3] < $c2->[3])
+                               && overlaps_axis($c1, $c2, 0)
+                               && overlaps_axis($c1, $c2, 2)) {
+                               my @c = @$c2;
+                               $c[3] = $c1->[3];
+                               push @nonint, [ @c ];
+                               @c = @$c2;
+                               $c[2] = $c1->[3]+1;
+                               push @nonint, [ @c ];
+                               say "split at ymax=$c1->[3] :\n", join(',', @{ $nonint[-2] }), "\n", join(',', @{ $nonint[-1] }) ;
+                               next;
+                       }
+                       if (($c1->[4] > $c2->[4] && $c1->[4] <= $c2->[5])
+                               && overlaps_axis($c1, $c2, 0)
+                               && overlaps_axis($c1, $c2, 1)) {
+                               my @c = @$c2;
+                               $c[5] = $c1->[4]-1;
+                               push @nonint, [ @c ];
+                               @c = @$c2;
+                               $c[4] = $c1->[4];
+                               push @nonint, [ @c ];
+                               say "split at zmin=$c1->[4] :\n", join(',', @{ $nonint[-2] }), "\n", join(',', @{ $nonint[-1] }) ;
+                               next;
+                       }
+                       if (($c1->[5] >= $c2->[4] && $c1->[5] < $c2->[5])
+                               && overlaps_axis($c1, $c2, 0)
+                               && overlaps_axis($c1, $c2, 1)) {
+                               my @c = @$c2;
+                               $c[5] = $c1->[5];
+                               push @nonint, [ @c ];
+                               @c = @$c2;
+                               $c[4] = $c1->[5]+1;
+                               push @nonint, [ @c ];
+                               say "split at zmax=$c1->[5] :\n", join(',', @{ $nonint[-2] }), "\n", join(',', @{ $nonint[-1] }) ;
+                               next;
+                       }
+               if (($c1->[0] <= $c2->[0] && $c1->[1] >= $c2->[1])
+                       && ($c1->[2] <= $c2->[2] && $c1->[3] >= $c2->[3])
+                       && ($c1->[4] <= $c2->[4] && $c1->[5] >= $c2->[5])) {
+                       say "[", join(',', @$c1), "] fully encloses \n[", join(',', @$c2), "] = enclosed";
+               } else {
+                       say "[", join(',', @$c1), "] and\n[", join(',', @$c2), "] do not overlap";
+                       push @nonint2, $c2;
+               }
+       }
+       push @nonint2, $c1 if $c1->[6];
+       @nonint = @nonint2;
+
+my $count;
+for my $c1 (@nonint) {
+       my $size = ($c1->[1] - $c1->[0] + 1)
+               * ($c1->[3] - $c1->[2] + 1)
+               * ($c1->[5] - $c1->[4] + 1);
+       say "final: [", join(',', @$c1), "] = $size";
+       $count += $size;
+}
+
+say $count;
+
+}