]> www.fi.muni.cz Git - aoc.git/commitdiff
Day 18: quite fast program, but slow to write
authorJan "Yenya" Kasprzak <kas@fi.muni.cz>
Mon, 18 Dec 2023 09:00:32 +0000 (10:00 +0100)
committerJan "Yenya" Kasprzak <kas@fi.muni.cz>
Mon, 18 Dec 2023 09:00:32 +0000 (10:00 +0100)
2023/35.pl [new file with mode: 0755]
2023/36.pl [new file with mode: 0755]

diff --git a/2023/35.pl b/2023/35.pl
new file mode 100755 (executable)
index 0000000..307d9f4
--- /dev/null
@@ -0,0 +1,76 @@
+#!/usr/bin/perl -w
+
+use v5.38;
+use experimental 'multidimensional';
+$; = ';';
+
+my ($x, $y) = (1000, 1000);
+my ($xmin, $xmax, $ymin, $ymax) = (1000) x 4;
+my %dir = (
+       R => [ 1,  0 ],
+       D => [ 0,  1 ],
+       L => [ -1, 0 ],
+       U => [ 0, -1 ],
+);
+
+my %map;
+while (<>) {
+       my ($dir, $len, $col) = /^(.) (\d+) \(\#(\w+)\)/;
+       say "at $x,$y dir $dir len $len col $col";
+       while ($len--){
+               $x += $dir{$dir}->[0];
+               $y += $dir{$dir}->[1];
+               say "    at $x,$y len $len";
+
+               $xmax = $x if $xmax < $x;
+               $ymax = $y if $ymax < $y;
+               $xmin = $x if $xmin > $x;
+               $ymin = $y if $ymin > $y;
+
+               $map{$x,$y} = $col;
+       }
+}
+
+say "$xmin..$xmax x $ymin..$ymax";
+
+my $sum;
+for my $y ($ymin .. $ymax) {
+       my $in = 0;
+       my $from = 0;
+       for my $x ($xmin .. $xmax) {
+               if ($map{$x,$y}) {
+                       $sum++;
+                       if ($map{$x,$y-1} && $map{$x,$y+1}) {
+                               $in = !$in;
+                               $from = 0;
+                       } elsif ($map{$x,$y-1}) {
+                               if ($from == 1) {
+                                       $in = !$in;
+                                       $from = 0;
+                               } elsif ($from == 0) {
+                                       $from = -1;
+                               } else {
+                                       $from = 0;
+                               }
+                       } elsif ($map{$x,$y+1}) {
+                               if ($from == -1) {
+                                       $in = !$in;
+                                       $from = 0;
+                               } elsif ($from == 0) {
+                                       $from = 1;
+                               } else {
+                                       $from = 0;
+                               }
+                       }
+                       print '#';
+               } else {
+                       $sum++ if $in;
+                       print $map{$x,$y} || $in ? 'O' : '.';
+               }
+       }
+       print "\n";
+}
+
+
+asay $sum;
+
diff --git a/2023/36.pl b/2023/36.pl
new file mode 100755 (executable)
index 0000000..956c980
--- /dev/null
@@ -0,0 +1,95 @@
+#!/usr/bin/perl -w
+
+use v5.38;
+
+my ($x, $y) = (20_000_000, 20_000_000);
+my %dir = (
+       0 => [ 1,  0 ],
+       1 => [ 0,  1 ],
+       2 => [ -1, 0 ],
+       3 => [ 0, -1 ],
+);
+
+my %map;
+my %dirs;
+while (<>) {
+       my ($len, $dir) = /\(\#(\w+)(\w)\)/;
+       $len = hex $len;
+       $map{$y}{$x} |= (1 << $dir);
+       $x += $len * $dir{$dir}->[0];
+       $y += $len * $dir{$dir}->[1];
+       $map{$y}{$x} |= (1 << ($dir ^ 2));
+       say "at $x,$y dir $dir len $len";
+}
+
+sub sum_int {
+       my @pts = @_;
+       my $sum = 0;
+       my $in;
+       my $prev;
+       for my $pt (@pts) {
+               if (defined $prev && $in) {
+                       $sum += $pt - $prev + 1;
+               }
+               $prev = $pt;
+               $in = !$in;
+       }
+       return $sum;
+}
+
+my @pts;
+my $y0;
+my $sum;
+for my $y1 (sort { $a <=> $b } keys %map) {
+       say "y $y1";
+       my $in;
+       my $x0;
+       my @nx;
+       my @tx;
+       my $rowsum;
+       if (defined $y0) {
+               my $psum = sum_int(@pts);
+               $sum += ($y1-$y0-1) * $psum;
+       }
+
+       for my $x1 (sort { $a <=> $b } (@pts, keys %{ $map{$y1} })) {
+               next if $x0 && $x1 == $x0;
+               my $d = $map{$y1}{$x1};
+               my $d0 = $map{$y1}{$x0} if defined $x0;
+               say " at $x1,$y1 ", $d // "|";
+               push @nx, $x1
+                       if !defined $d || ($d & 2);
+               if (!defined $d) {
+                       push @tx, $x1;
+               } elsif ($d & 4) {
+                       if (@tx & 1) {
+                               if (($d0 == 9 && $d == 6) || ($d0 == 3 && $d == 12)) {
+                                       push @tx, $x1;
+                               }
+                       } else {
+                               push @tx, $x0;
+                               if (($d0 == 9 && $d == 12) || ($d0 == 3 && $d == 6)) {
+                                       push @tx, $x1;
+                               }
+                       }
+               }
+
+               if (defined $x0) {
+                       say "   int $x0 .. $x1";
+                       
+                       $in = !$in;
+                       if ($in) {
+                               $rowsum += $x1 - $x0 + 1;
+                       }
+               }
+               $x0 = $x1;
+       }
+       $sum += sum_int(@tx);
+       say " tx=@tx sum ", sum_int(@tx);
+       say " nx=@nx sum ", sum_int(@nx);
+       @pts = @nx;
+       $y0 = $y1;
+}
+
+say $sum;
+