diff --git a/2023/07/Part2.pm b/2023/07/Part2.pm index c907947..cc89c80 100644 --- a/2023/07/Part2.pm +++ b/2023/07/Part2.pm @@ -4,11 +4,65 @@ package Part2; use Part1; -use List::AllUtils qw/ /; +use List::AllUtils qw/ pairmap sum max /; +use List::UtilsBy qw/ sort_by /; +sub rank_hand(@hand) { + @hand = split '', shift @hand if @hand == 1; + + my %group; + $group{$_}++ for @hand; + + my $jokers = delete $group{'`'} // 0; + + return 7 if 1 >= keys %group; + + return 6 if grep { $_+$jokers >= 4 } values %group; + + my $max = max values %group; + + if( $max + $jokers >= 3 ) { + return 5 if keys %group <= 2; + return 4; + } + + return 3 if keys %group == 3; + + return 2 if keys %group == 4; + + return 1; +} + +sub handify($str) { + state %map = ( + 'T' => 10, + 'J' => 1, + 'Q' => 12, + 'K' => 13, + A => 14 + ); + + my @cards = map { chr( ord('a') + $_ - 2 )} map { $map{$_} // $_ } split '', $str; + + return \@cards; +} + +sub parse_input($input) { + my @lines = split "\n", $input; + my @hand_score = pairmap { + [ handify($a), $b] + } map { split " " } @lines; + return @hand_score; +} + +sub score(@hand) { + join '', rank_hand(@hand), @hand; +} sub solution_2 ($input) { - ...; + my @hand_score = sort_by { score($_->[0]->@*) } parse_input($input); + my $rank = 0; + return sum map { ++$rank * $_->[1] } @hand_score; } 1; diff --git a/2023/07/benchmark.pl b/2023/07/benchmark.pl index 36ab17c..d0ffeee 100644 --- a/2023/07/benchmark.pl +++ b/2023/07/benchmark.pl @@ -36,6 +36,7 @@ for my $part (@parts) { language => 'perl', part => $part->{part}, time => $res->cpu_a / $res->iters, + persec => $res->iters / $res->cpu_a , timestamp => DateTime->now->iso8601, }; say to_json $result; diff --git a/2023/07/part2.t b/2023/07/part2.t index 0401ccc..34c6180 100644 --- a/2023/07/part2.t +++ b/2023/07/part2.t @@ -7,7 +7,11 @@ use Path::Tiny; use Part2; my $input = path('input')->slurp; +my $example = path('example')->slurp; -is Part2::solution_2($input) => 'TODO'; +is Part2::solution_2($example) => 5905; + +cmp_ok Part2::solution_2($input), '<' => 250843163; +is Part2::solution_2($input) => 250506580; done_testing; diff --git a/2023/07/solutions.yml b/2023/07/solutions.yml index 1f1ab68..513f041 100644 --- a/2023/07/solutions.yml +++ b/2023/07/solutions.yml @@ -1,2 +1,2 @@ 1: 250058342 -2: TODO +2: 250506580 diff --git a/2023/benchmark.json b/2023/benchmark.json index e1feac8..b264505 100644 --- a/2023/benchmark.json +++ b/2023/benchmark.json @@ -14,4 +14,5 @@ {"timestamp":"2023-12-05T23:24:38","persec":79.2380952380952,"year":"2023","day":"5","part":2,"time":0.0126201923076923,"language":"perl"} {"year":"2023","part":1,"day":"6","language":"perl","time":1.43016642439049e-05,"timestamp":"2023-12-06T15:43:00","persec":69921.9323671498} {"year":"2023","part":2,"language":"perl","day":"6","time":7.07875059716474e-06,"timestamp":"2023-12-06T15:43:13","persec":141267.867298578} - +{"language":"perl","persec":85.2380952380952,"year":"2023","timestamp":"2023-12-07T16:08:30","time":0.011731843575419,"part":1,"day":"7"} +{"day":"7","part":2,"persec":85.2380952380952,"year":"2023","timestamp":"2023-12-07T16:08:43","time":0.011731843575419,"language":"perl"}