aoc2022

Advent of Code 2022 solutions in Perl.
git clone git://git.samirparikh.com/aoc2022
Log | Files | Refs | README

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:
Aday11/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 ];