adventofcode/2023/07/Part2.pm

71 lines
1.3 KiB
Perl
Raw Normal View History

2023-12-07 15:01:29 +00:00
use 5.38.0;
package Part2;
use Part1;
2023-12-07 16:10:22 +00:00
use List::AllUtils qw/ pairmap sum max /;
2023-12-07 16:23:53 +00:00
use List::UtilsBy qw/ sort_by /;
2023-12-07 15:01:29 +00:00
2023-12-07 16:23:53 +00:00
sub rank_hand (@hand) {
2023-12-07 16:10:22 +00:00
@hand = split '', shift @hand if @hand == 1;
my %group;
$group{$_}++ for @hand;
my $jokers = delete $group{'`'} // 0;
return 7 if 1 >= keys %group;
2023-12-07 16:23:53 +00:00
return 6 if grep { $_ + $jokers >= 4 } values %group;
2023-12-07 16:10:22 +00:00
my $max = max values %group;
2023-12-07 16:23:53 +00:00
if ( $max + $jokers >= 3 ) {
2023-12-07 16:10:22 +00:00
return 5 if keys %group <= 2;
return 4;
}
return 3 if keys %group == 3;
return 2 if keys %group == 4;
return 1;
}
2023-12-07 16:23:53 +00:00
sub handify ($str) {
2023-12-07 16:10:22 +00:00
state %map = (
'T' => 10,
'J' => 1,
'Q' => 12,
'K' => 13,
2023-12-07 16:23:53 +00:00
A => 14
2023-12-07 16:10:22 +00:00
);
2023-12-07 16:23:53 +00:00
my @cards =
map { chr( ord('a') + $_ - 2 ) } map { $map{$_} // $_ } split '', $str;
2023-12-07 16:10:22 +00:00
return \@cards;
}
2023-12-07 16:23:53 +00:00
sub parse_input ($input) {
my @lines = split "\n", $input;
my @hand_score = pairmap {
[ handify($a), $b ]
}
map { split " " } @lines;
2023-12-07 16:10:22 +00:00
return @hand_score;
}
2023-12-07 16:23:53 +00:00
sub score (@hand) {
2023-12-07 16:10:22 +00:00
join '', rank_hand(@hand), @hand;
}
2023-12-07 15:01:29 +00:00
sub solution_2 ($input) {
2023-12-07 16:23:53 +00:00
my @hand_score = sort_by { score( $_->[0]->@* ) } parse_input($input);
my $rank = 0;
2023-12-07 16:10:22 +00:00
return sum map { ++$rank * $_->[1] } @hand_score;
2023-12-07 15:01:29 +00:00
}
1;