]> www.fi.muni.cz Git - aoc.git/commitdiff
Day 5: minimizing number of if-branches
authorJan "Yenya" Kasprzak <kas@fi.muni.cz>
Tue, 5 Dec 2023 06:40:45 +0000 (07:40 +0100)
committerJan "Yenya" Kasprzak <kas@fi.muni.cz>
Tue, 5 Dec 2023 06:52:33 +0000 (07:52 +0100)
2023/09.pl [new file with mode: 0755]
2023/10.pl [new file with mode: 0755]

diff --git a/2023/09.pl b/2023/09.pl
new file mode 100755 (executable)
index 0000000..0c9077f
--- /dev/null
@@ -0,0 +1,26 @@
+#!/usr/bin/perl -w
+
+use v5.38;
+use List::Util qw(min);
+
+$/ = "\n\n";
+my @seeds = scalar(<>) =~ /\d+/g;
+say join ",", @seeds;
+
+while (<>) {
+       chomp;
+       my @rules = split /\n/;
+       say shift @rules;
+       @rules = map { [ /\d+/g ] } @rules;
+       for (@seeds) {
+               for my $rule (@rules) {
+                       if ($_ >= $rule->[1] && $_ < $rule->[1] + $rule->[2]) {
+                               $_ = $rule->[0] + $_ - $rule->[1];
+                               last;
+                       } 
+               }
+       }
+       say join ",", @seeds;
+}
+
+say min @seeds;
diff --git a/2023/10.pl b/2023/10.pl
new file mode 100755 (executable)
index 0000000..a198d75
--- /dev/null
@@ -0,0 +1,51 @@
+#!/usr/bin/perl -w
+
+use v5.38;
+use experimental 'for_list';
+use List::Util qw(min);
+
+$/ = "\n\n";
+my @seeds = map { $_ } scalar(<>) =~ /\d+/g;
+my @ranges;
+for my ($st, $ct) (@seeds) {
+       push @ranges, [ $st, $ct];
+}
+
+while (<>) {
+       chomp;
+       my @rules = split /\n/;
+       say shift @rules;
+       @rules = map { [ /\d+/g ] } @rules;
+       my @nranges;
+RANGE:
+       while (@ranges) {
+               my $range = shift @ranges;
+               my ($g0, $gn) = @$range;
+               $gn += $g0 - 1;
+
+               for my $rule (@rules) {
+                       my ($d0, $r0, $rn) = @$rule;
+                       $rn += $r0 - 1;
+                       next if $gn < $r0 || $g0 > $rn; # no overlap
+                       if ($g0 >= $r0 && $gn <= $rn) { # contained
+                               push @nranges, [ $g0+$d0-$r0, $gn-$g0+1 ];
+                               next RANGE;
+                       }
+                       if ($g0 < $r0 && $gn >= $r0) { # end of range overlap
+                               push @ranges, [ $g0, $r0-$g0 ],
+                                       [ $r0, $gn-$r0+1 ];
+                               next RANGE;
+                       }
+                       if ($g0 >= $r0 && $g0 <= $rn) { # start of range ovlp
+                               push @ranges, [ $g0, $rn-$g0+1 ],
+                                       [ $rn+1, $gn-$rn ];
+                               next RANGE;
+                       }
+               }
+               push @nranges, $range; # no match
+       }
+       @ranges = @nranges;
+       say map { $_->[0], '+', $_->[1], ' ' } @ranges;
+}
+
+say min map { $_->[0] } @ranges;