]> www.fi.muni.cz Git - aoc.git/blob - 2023/10.pl
Day 5: minimizing number of if-branches
[aoc.git] / 2023 / 10.pl
1 #!/usr/bin/perl -w
2
3 use v5.38;
4 use experimental 'for_list';
5 use List::Util qw(min);
6
7 $/ = "\n\n";
8 my @seeds = map { $_ } scalar(<>) =~ /\d+/g;
9 my @ranges;
10 for my ($st, $ct) (@seeds) {
11         push @ranges, [ $st, $ct];
12 }
13
14 while (<>) {
15         chomp;
16         my @rules = split /\n/;
17         say shift @rules;
18         @rules = map { [ /\d+/g ] } @rules;
19         my @nranges;
20 RANGE:
21         while (@ranges) {
22                 my $range = shift @ranges;
23                 my ($g0, $gn) = @$range;
24                 $gn += $g0 - 1;
25
26                 for my $rule (@rules) {
27                         my ($d0, $r0, $rn) = @$rule;
28                         $rn += $r0 - 1;
29                         next if $gn < $r0 || $g0 > $rn; # no overlap
30                         if ($g0 >= $r0 && $gn <= $rn) { # contained
31                                 push @nranges, [ $g0+$d0-$r0, $gn-$g0+1 ];
32                                 next RANGE;
33                         }
34                         if ($g0 < $r0 && $gn >= $r0) { # end of range overlap
35                                 push @ranges, [ $g0, $r0-$g0 ],
36                                         [ $r0, $gn-$r0+1 ];
37                                 next RANGE;
38                         }
39                         if ($g0 >= $r0 && $g0 <= $rn) { # start of range ovlp
40                                 push @ranges, [ $g0, $rn-$g0+1 ],
41                                         [ $rn+1, $gn-$rn ];
42                                 next RANGE;
43                         }
44                 }
45                 push @nranges, $range; # no match
46         }
47         @ranges = @nranges;
48         say map { $_->[0], '+', $_->[1], ' ' } @ranges;
49 }
50
51 say min map { $_->[0] } @ranges;