]> www.fi.muni.cz Git - aoc.git/commitdiff
Day 20: examining the input
authorJan "Yenya" Kasprzak <kas@fi.muni.cz>
Wed, 20 Dec 2023 07:35:53 +0000 (08:35 +0100)
committerJan "Yenya" Kasprzak <kas@fi.muni.cz>
Wed, 20 Dec 2023 07:35:53 +0000 (08:35 +0100)
2023/39.pl [new file with mode: 0755]
2023/40.pl [new file with mode: 0755]

diff --git a/2023/39.pl b/2023/39.pl
new file mode 100755 (executable)
index 0000000..21aa5d7
--- /dev/null
@@ -0,0 +1,54 @@
+#!/usr/bin/perl -w
+
+use v5.38;
+use List::Util qw(product);
+
+my %types;
+my %dests;
+my %ffs;
+my %inps;
+
+while (<>) {
+       my ($src, @dst) = /\w+/g;
+       ($types{$src}) = /^(\W)/;
+       @{ $dests{$src} } = @dst;
+       $inps{$_}->{$src} = 0 for @dst;
+}
+
+my @sums = (0, 0);
+
+sub snd {
+       my ($q, $name, $pulse) = @_;
+       for (@{ $dests{$name} }) {
+               push @$q, [ $_ , $pulse, $name ];
+               $sums[$pulse]++;
+       }
+}
+
+for (1 .. 1000) {
+       my @q = ([ 'broadcaster', 0, 'button' ]);
+       $sums[0]++;
+       while (@q) {
+               my $p = shift @q;
+               my ($name, $pulse, $origin) = @$p;
+               my $type = $types{$name} // '';
+
+               if ($type eq '%') {
+                       if (!$pulse) {
+                               $ffs{$name} = !$ffs{$name};
+                               snd(\@q, $name, $ffs{$name});
+                       }
+               } elsif ($type eq '&') {
+                       my $in = $inps{$name};
+                       $in->{$origin} = $pulse;
+                       my $out = 1;
+                       $out *= $_ for values %$in;
+                       snd(\@q, $name, !$out);
+               } else {
+                       snd(\@q, $name, 0);
+               }
+       }
+}
+
+say "@sums -> ", product @sums;
+
diff --git a/2023/40.pl b/2023/40.pl
new file mode 100755 (executable)
index 0000000..0dedede
--- /dev/null
@@ -0,0 +1,66 @@
+#!/usr/bin/perl -w
+
+use v5.38;
+use List::Util qw(product);
+
+my %types;
+my %dests;
+my %ffs;
+my %inps;
+
+while (<>) {
+       my ($src, @dst) = /\w+/g;
+       ($types{$src}) = /^(\W)/;
+       @{ $dests{$src} } = @dst;
+       $inps{$_}->{$src} = 0 for @dst;
+}
+
+my $iters;
+
+my ($mainnode) = keys %{ $inps{rx} };
+my %prev;
+my %recv;
+my %period;
+sub snd {
+       my ($q, $name, $pulse) = @_;
+       $pulse = $pulse ? 1 : 0;
+       for (@{ $dests{$name} }) {
+               push @$q, [ $_ , $pulse, $name ];
+               if ($_ eq $mainnode && $pulse) {
+                       my $p = $prev{$name};
+                       $prev{$name} = $iters;
+                       next if !$p;
+                       $period{$name} = $iters - $p;
+                       say "$name -$pulse-> $_ $period{$name}";
+               }
+               $recv{$_}->[$pulse]++;
+       }
+}
+
+while (grep { !$period{$_} } keys %{ $inps{$mainnode} }) {
+       %recv = ();
+       $iters++;
+       my @q = ([ 'broadcaster', 0, 'button' ]);
+       while (@q) {
+               my $p = shift @q;
+               my ($name, $pulse, $origin) = @$p;
+               my $type = $types{$name} // '';
+
+               if ($type eq '%') {
+                       if (!$pulse) {
+                               $ffs{$name} = !$ffs{$name};
+                               snd(\@q, $name, $ffs{$name});
+                       }
+               } elsif ($type eq '&') {
+                       my $in = $inps{$name};
+                       $in->{$origin} = $pulse;
+                       my $out = 1;
+                       $out *= $_ for values %$in;
+                       snd(\@q, $name, !$out);
+               } else {
+                       snd(\@q, $name, 0);
+               }
+       }
+}
+
+say product map { $period{$_} } keys %{ $inps{$mainnode} };