Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/usr/bin/perl
- use strict;
- use warnings;
- use feature qw(say);
- use List::Util qw(reduce product);
- # Read in circuit
- my %Circ;
- while (<>) {
- my ($type, $name, $out) = m#(.)(\w+) -> (.*)#;
- $name = 'broadcaster' if ($type eq 'b');
- my @out = split( /, /, $out );
- $Circ{$name}{type} = $type;
- $Circ{$name}{out} = [@out];
- push( $Circ{$_}{in}->@*, $name ) foreach (@out);
- }
- my @pulses = (0, 0); # counts of low (0) and high (1) pulses
- foreach (1 .. 1000) {
- # broadcaster is honourary flip-flop, always starts high
- $Circ{broadcaster}{state} = 1;
- my @queue = ([0, 'broadcaster', 'button']);
- PULSE:
- while (my $pulse = shift @queue) {
- my ($bit, $targ, $src) = @$pulse;
- $pulses[$bit]++;
- next PULSE if (!defined $Circ{$targ}{type}); # output only nodes
- if ($Circ{$targ}{type} eq '&') { # NAND
- $Circ{$targ}{$src} = $bit;
- my $state = int !(reduce {$a & $b} (1, map {$Circ{$targ}{$_} // 0} $Circ{$targ}{in}->@*));
- push( @queue, map { [$state, $_, $targ] } $Circ{$targ}{out}->@* );
- } else { # flip-flop or 'b'roadcast
- next PULSE if ($bit);
- my $state = $Circ{$targ}{state} = int !($Circ{$targ}{state} // 0);
- push( @queue, map { [$state, $_, $targ] } $Circ{$targ}{out}->@* );
- }
- }
- }
- say "Pulses: ", join( ', ', @pulses );
- say "Part 1: ", product @pulses;
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement