commit 57d851b9ce3c419e041b1bd6bcaeca8f9db032a0
parent 22b3dbc918368c5c876a085e659e7fe82291d965
Author: Samir Parikh <noreply@samirparikh.com>
Date: Mon, 2 Jan 2023 18:07:14 +0000
solve part 2 of day11
Diffstat:
A | day11/day11.2.pl | | | 116 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
1 file changed, 116 insertions(+), 0 deletions(-)
diff --git a/day11/day11.2.pl b/day11/day11.2.pl
@@ -0,0 +1,116 @@
+#!/usr/local/bin/perl
+# day 2022-11
+
+use strict;
+use warnings;
+use v5.32;
+
+use List::Util qw( product );
+
+use Log::Log4perl ();
+use Log::Log4perl::Level ();
+Log::Log4perl->easy_init(
+ Log::Log4perl::Level::to_priority( 'OFF' )
+); # set to 'OFF', 'INFO', 'DEBUG' or 'TRACE' for successively more information
+my $logger = Log::Log4perl->get_logger();
+
+@ARGV = "input" unless @ARGV;
+$/ = ''; # set to paragraph mode. Each monkey is treated as one record
+my @input = <>;
+
+my $ITEMS = "items";
+my $OPERATION = "Operation";
+my $TEST = "Test";
+my $TRUE = "true";
+my $FALSE = "false";
+my $ROUNDS = 10000;
+
+sub init_monkeys {
+ my @input = @_;
+ my @monkeys;
+ foreach my $monkey ( @input ) {
+ my %monkey;
+ foreach my $attribute ( split /\n/, $monkey ) {
+ next if ( $attribute =~ m/Monkey/ );
+ my ( $key, $value ) = split /:/ => $attribute;
+ if ( $key =~ m/$ITEMS/ ) {
+ $value =~ s/\s//g;
+ $monkey{ $ITEMS } = [ split /,/ => $value ];
+ } elsif ( $key =~ m/$OPERATION/ ) {
+ my %operation;
+ my ( $operation, $operand ) = $value =~ m/(\+|\*) (.+)/;
+ $monkey{ $OPERATION } = { "operation" => $operation,
+ "operand" => $operand,
+ };
+ } elsif ( $key =~ m/$TEST/ ) {
+ ( $monkey{ $TEST } ) = $value =~ m/(\d+)/;
+ } elsif ( $key =~ m/$TRUE/ ) {
+ ( $monkey{ $TRUE } ) = $value =~ m/(\d+)/;
+ } elsif ( $key =~ m/$FALSE/ ) {
+ ( $monkey{ $FALSE } ) = $value =~ m/(\d+)/;
+ } else {
+ die "Could not parse attribute $attribute";
+ }
+ }
+ push @monkeys => \%monkey;
+ }
+ return @monkeys;
+}
+
+my @monkeys1 = init_monkeys( @input );
+my %monkeys1_count;
+
+my $modulo = 1;
+$modulo *= $_->{ $TEST } foreach ( @monkeys1 );
+$logger->trace( "modulo = $modulo" );
+
+foreach my $round ( 1 .. $ROUNDS ) {
+ my $num = 0;
+ foreach my $monkey ( @monkeys1 ) {
+ $logger->trace( "Monkey $num:" );
+ while ( @{ $monkey->{ $ITEMS } } ) {
+ my $item = shift @{ $monkey->{ $ITEMS } };
+ $logger->trace( " Monkey inspects an item with a worry level of $item." );
+ $monkeys1_count{ $num }++;
+ my $expression = join " ",
+ $item,
+ $monkey->{ $OPERATION }{ operation },
+ $monkey->{ $OPERATION }{ operand } eq 'old' ? $item :
+ $monkey->{ $OPERATION }{ operand };
+ $item = eval $expression;
+ $item = $item % $modulo;
+ $logger->trace( " Worry level is now $item." );
+ #$item = int( $item / 3 );
+ #$logger->trace(" Monkey gets bored with item. ",
+ # "Worry level is divided by 3 to $item.");
+ if ( $item % $monkey->{ $TEST } == 0 ) { # true
+ $logger->trace( " Current worry level is divisible by ",
+ "$monkey->{ $TEST }." );
+ $logger->trace( " Item with worry level $item is thrown to monkey ",
+ "$monkey->{ $TRUE }." );
+ push @{ $monkeys1[ $monkey->{ $TRUE } ]->{ $ITEMS } } => $item;
+ } else { # false
+ $logger->trace( " Current worry level is not divisible by ",
+ "$monkey->{ $TEST }." );
+ $logger->trace( " Item with worry level $item is thrown to monkey ",
+ "$monkey->{ $FALSE }." );
+ push @{ $monkeys1[ $monkey->{ $FALSE } ]->{ $ITEMS } } => $item;
+ }
+ }
+ $num++;
+ }
+
+ $logger->debug( "After round $round, the monkeys are holding items with these ",
+ "worry levels:" );
+ foreach my $i ( 0 .. $#monkeys1 ) {
+ $logger->debug( "Monkey $i: ",
+ ( join ", ", @{ $monkeys1[ $i ]->{ $ITEMS } } ) );
+ }
+}
+
+foreach my $monkey ( sort keys %monkeys1_count ) {
+ $logger->info( "Monkey $monkey inspected items $monkeys1_count{ $monkey } times." );
+}
+
+my @inspections = reverse( sort { $a <=> $b } ( values %monkeys1_count ) );
+say "part 2: ", product @inspections[ 0 .. 1 ];