This commit is contained in:
Yanick Champoux 2023-12-07 11:23:53 -05:00
parent 482ae97ee6
commit 046cb8f538
6 changed files with 48 additions and 44 deletions

1
2023/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
*.bak

View File

@ -3,9 +3,9 @@ use 5.38.0;
package Part1; package Part1;
use List::AllUtils qw/ pairmap sum /; use List::AllUtils qw/ pairmap sum /;
use List::UtilsBy qw/ sort_by /; use List::UtilsBy qw/ sort_by /;
sub rank_hand(@hand) { sub rank_hand (@hand) {
@hand = split '', shift @hand if @hand == 1; @hand = split '', shift @hand if @hand == 1;
my %group; my %group;
@ -28,35 +28,38 @@ sub rank_hand(@hand) {
return 1; return 1;
} }
sub handify($str) { sub handify ($str) {
state %map = ( state %map = (
'T' => 10, 'T' => 10,
'J' => 11, 'J' => 11,
'Q' => 12, 'Q' => 12,
'K' => 13, 'K' => 13,
A => 14 A => 14
); );
my @cards = map { chr( ord('a') + $_ - 2 )} map { $map{$_} // $_ } split '', $str; my @cards =
map { chr( ord('a') + $_ - 2 ) } map { $map{$_} // $_ } split '', $str;
return \@cards; return \@cards;
} }
sub parse_input($input) { sub parse_input ($input) {
my @lines = split "\n", $input; my @lines = split "\n", $input;
my @hand_score = pairmap { my @hand_score = pairmap {
[ handify($a), $b] [ handify($a), $b ]
} map { split " " } @lines; }
map { split " " } @lines;
return @hand_score; return @hand_score;
} }
sub score(@hand) { sub score (@hand) {
join '', rank_hand(@hand), @hand; join '', rank_hand(@hand), @hand;
} }
sub solution_1 ($input) { sub solution_1 ($input) {
my @hand_score = sort_by { score($_->[0]->@*) } parse_input($input); my @hand_score = sort_by { score( $_->[0]->@* ) } parse_input($input);
my $rank = 0; my $rank = 0;
# use DDP; p @hand_score; # use DDP; p @hand_score;
return sum map { ++$rank * $_->[1] } @hand_score; return sum map { ++$rank * $_->[1] } @hand_score;
} }

View File

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

View File

@ -9,8 +9,8 @@ use File::Serialize;
use Part1; use Part1;
use Part2; use Part2;
my $day = path('.')->absolute->basename =~ s/^0//r; my $day = path('.')->absolute->basename =~ s/^0//r;
my $year = path('.')->absolute->parent->basename; my $year = path('.')->absolute->parent->basename;
my $solutions = deserialize_file('solutions.yml'); my $solutions = deserialize_file('solutions.yml');
my @parts = ( my @parts = (
@ -36,7 +36,7 @@ for my $part (@parts) {
language => 'perl', language => 'perl',
part => $part->{part}, part => $part->{part},
time => $res->cpu_a / $res->iters, time => $res->cpu_a / $res->iters,
persec => $res->iters / $res->cpu_a , persec => $res->iters / $res->cpu_a,
timestamp => DateTime->now->iso8601, timestamp => DateTime->now->iso8601,
}; };
say to_json $result; say to_json $result;

View File

@ -6,22 +6,20 @@ use Path::Tiny;
use Part1; use Part1;
my $input = path('input')->slurp; my $input = path('input')->slurp;
my $example = path('example')->slurp; my $example = path('example')->slurp;
is Part1::rank_hand( 'AAAAA') => 7; is Part1::rank_hand('AAAAA') => 7;
is Part1::rank_hand( 'AA8AA') => 6; is Part1::rank_hand('AA8AA') => 6;
is Part1::rank_hand( '23332') => 5; is Part1::rank_hand('23332') => 5;
is Part1::rank_hand( 'TTT98') => 4; is Part1::rank_hand('TTT98') => 4;
is Part1::rank_hand( '23432') => 3; is Part1::rank_hand('23432') => 3;
is Part1::rank_hand( 'A23A4') => 2; is Part1::rank_hand('A23A4') => 2;
is Part1::rank_hand( '23456') => 1; is Part1::rank_hand('23456') => 1;
is [ Part1::parse_input( '2345A 123') ] => [ is [ Part1::parse_input('2345A 123') ] => [ [ [qw/ a b c d m /], 123 ] ];
[ [qw/ a b c d m /], 123 ]
];
is Part1::solution_1($example) => 6440; is Part1::solution_1($example) => 6440;
is Part1::solution_1($input) => 'TODO'; is Part1::solution_1($input) => 'TODO';
done_testing; done_testing;

View File

@ -6,7 +6,7 @@ use Path::Tiny;
use Part2; use Part2;
my $input = path('input')->slurp; my $input = path('input')->slurp;
my $example = path('example')->slurp; my $example = path('example')->slurp;
is Part2::solution_2($example) => 5905; is Part2::solution_2($example) => 5905;