From f847e88016fb7eaf6745e39b939fee43db0f96ef Mon Sep 17 00:00:00 2001 From: "Jan \"Yenya\" Kasprzak" Date: Wed, 22 Dec 2021 07:53:20 +0100 Subject: [PATCH] Day 22: copy&paste in 3D, and don't make a mistake --- 43.pl | 38 +++++++++++++++++ 44.pl | 133 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 171 insertions(+) create mode 100755 43.pl create mode 100755 44.pl diff --git a/43.pl b/43.pl new file mode 100755 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 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; + +} -- 2.43.5