Advertisement
musifter

AoC 2023 day 20, part 1 (Perl)

Dec 20th, 2023
1,005
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Perl 1.46 KB | Source Code | 0 0
  1. #!/usr/bin/perl
  2.  
  3. use strict;
  4. use warnings;
  5.  
  6. use feature         qw(say);
  7. use List::Util      qw(reduce product);
  8.  
  9. # Read in circuit
  10. my %Circ;
  11. while (<>) {
  12.     my ($type, $name, $out) = m#(.)(\w+) -> (.*)#;
  13.  
  14.     $name = 'broadcaster' if ($type eq 'b');
  15.  
  16.     my @out = split( /, /, $out );
  17.  
  18.     $Circ{$name}{type} = $type;
  19.     $Circ{$name}{out}  = [@out];
  20.     push( $Circ{$_}{in}->@*, $name )  foreach (@out);
  21. }
  22.  
  23. my @pulses = (0, 0);        # counts of low (0) and high (1) pulses
  24.  
  25. foreach (1 .. 1000) {
  26.     # broadcaster is honourary flip-flop, always starts high
  27.     $Circ{broadcaster}{state} = 1;
  28.     my @queue = ([0, 'broadcaster', 'button']);
  29.  
  30.     PULSE:
  31.     while (my $pulse = shift @queue) {
  32.         my ($bit, $targ, $src) = @$pulse;
  33.  
  34.         $pulses[$bit]++;
  35.         next PULSE  if (!defined $Circ{$targ}{type});   # output only nodes
  36.  
  37.         if ($Circ{$targ}{type} eq '&') {  # NAND
  38.             $Circ{$targ}{$src} = $bit;
  39.  
  40.             my $state = int !(reduce {$a & $b} (1, map {$Circ{$targ}{$_} // 0} $Circ{$targ}{in}->@*));
  41.             push( @queue, map { [$state, $_, $targ] } $Circ{$targ}{out}->@* );
  42.  
  43.         } else {  # flip-flop or 'b'roadcast
  44.             next PULSE if ($bit);
  45.  
  46.             my $state = $Circ{$targ}{state} = int !($Circ{$targ}{state} // 0);
  47.             push( @queue, map { [$state, $_, $targ] } $Circ{$targ}{out}->@* );
  48.         }
  49.     }
  50. }
  51.  
  52. say "Pulses: ", join( ', ', @pulses );
  53. say "Part 1: ", product @pulses;
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement