]> www.fi.muni.cz Git - aoc.git/blob - 2023/40.pl
Day 25: examining the input
[aoc.git] / 2023 / 40.pl
1 #!/usr/bin/perl -w
2
3 use v5.38;
4 use List::Util qw(product);
5
6 my %types;
7 my %dests;
8 my %ffs;
9 my %inps;
10
11 while (<>) {
12         my ($src, @dst) = /\w+/g;
13         ($types{$src}) = /^(\W)/;
14         @{ $dests{$src} } = @dst;
15         $inps{$_}->{$src} = 0 for @dst;
16 }
17
18 my $iters;
19
20 my ($mainnode) = keys %{ $inps{rx} };
21 my %prev;
22 my %recv;
23 my %period;
24 sub snd {
25         my ($q, $name, $pulse) = @_;
26         $pulse = $pulse ? 1 : 0;
27         for (@{ $dests{$name} }) {
28                 push @$q, [ $_ , $pulse, $name ];
29                 if ($_ eq $mainnode && $pulse) {
30                         my $p = $prev{$name};
31                         $prev{$name} = $iters;
32                         next if !$p;
33                         $period{$name} = $iters - $p;
34                         say "$name -$pulse-> $_ $period{$name}";
35                 }
36                 $recv{$_}->[$pulse]++;
37         }
38 }
39
40 while (grep { !$period{$_} } keys %{ $inps{$mainnode} }) {
41         %recv = ();
42         $iters++;
43         my @q = ([ 'broadcaster', 0, 'button' ]);
44         while (@q) {
45                 my $p = shift @q;
46                 my ($name, $pulse, $origin) = @$p;
47                 my $type = $types{$name} // '';
48
49                 if ($type eq '%') {
50                         if (!$pulse) {
51                                 $ffs{$name} = !$ffs{$name};
52                                 snd(\@q, $name, $ffs{$name});
53                         }
54                 } elsif ($type eq '&') {
55                         my $in = $inps{$name};
56                         $in->{$origin} = $pulse;
57                         my $out = 1;
58                         $out *= $_ for values %$in;
59                         snd(\@q, $name, !$out);
60                 } else {
61                         snd(\@q, $name, 0);
62                 }
63         }
64 }
65
66 say product map { $period{$_} } keys %{ $inps{$mainnode} };