Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/usr/bin/perl
- use strict;
- use warnings;
- use Math::Utils qw(lcm floor);
- use Clone qw(clone);
- $| = 1;
- $/ = '';
- my @monkeys;
- my $modulus = 1;
- foreach (<>) {
- my @desc = split /\n/;
- my ($n) = (shift @desc) =~ m#(\d+)#;
- # Simple parse of label -> numbers
- my %p = map { (m#(\w+):#) => [m#(\d+)#g] } @desc;
- $monkeys[$n]{start} = $p{items}; # starting items
- # parse inspection rule
- $desc[1] =~ s#new = (.*)#$1#;
- $desc[1] =~ s#old#\$_[0]#g;
- $monkeys[$n]{op} = eval "sub { $desc[1] }";
- # make test rule sub
- $monkeys[$n]{pass} = eval "sub {(\$_[0] % $p{Test}[0] == 0) ? $p{true}[0] : $p{false}[0]}";
- $modulus = lcm( $modulus, $p{Test} );
- }
- sub run_monkeys {
- my ($rounds, $reduce) = @_;
- # Initialize
- foreach (@monkeys) {
- $_->{inspect} = 0;
- $_->{items} = clone( $_->{start} );
- }
- # Run rounds
- foreach (1 .. $rounds) {
- foreach my $monk (@monkeys) {
- $monk->{inspect} += @{$monk->{items}};
- while (my $item = shift @{$monk->{items}}) {
- $item = &$reduce( $monk->{op}( $item ) );
- push( @{$monkeys[$monk->{pass}($item)]{items}}, $item );
- }
- }
- }
- # Get results
- my @sort = sort { $b->{inspect} <=> $a->{inspect} } (@monkeys);
- return ($sort[0]->{inspect} * $sort[1]->{inspect});
- }
- print "Part 1: ", &run_monkeys( 20, sub { floor( $_[0] / 3 ) } ), "\n";
- print "Part 2: ", &run_monkeys( 10000, sub { $_[0] % $modulus } ), "\n";
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement