From 462dfc9c7fc9d4f28003d72f1117e563dafc0e22 Mon Sep 17 00:00:00 2001 From: Yanick Champoux Date: Wed, 6 Dec 2023 10:31:39 -0500 Subject: [PATCH 1/7] part 1 --- 2023/06/Part1.pm | 31 +++++++++++++++++++++++++++++++ 2023/06/Part2.pm | 14 ++++++++++++++ 2023/06/benchmark.pl | 41 +++++++++++++++++++++++++++++++++++++++++ 2023/06/example | 2 ++ 2023/06/part1.t | 20 ++++++++++++++++++++ 2023/06/part2.t | 13 +++++++++++++ 2023/06/solutions.yml | 2 ++ 7 files changed, 123 insertions(+) create mode 100644 2023/06/Part1.pm create mode 100644 2023/06/Part2.pm create mode 100644 2023/06/benchmark.pl create mode 100644 2023/06/example create mode 100644 2023/06/part1.t create mode 100644 2023/06/part2.t create mode 100644 2023/06/solutions.yml diff --git a/2023/06/Part1.pm b/2023/06/Part1.pm new file mode 100644 index 0000000..4613141 --- /dev/null +++ b/2023/06/Part1.pm @@ -0,0 +1,31 @@ +use 5.38.0; + +package Part1; + +use List::AllUtils qw/ product /; +use POSIX qw/ floor ceil /; + +sub my_zip($a,$b) { + return map { [ $a->[$_], $b->[$_] ] } 0..$a->@*-1; +} + +sub parse_file($input) { + my_zip( map { [/(\d+)/g ] } split "\n", $input ); +} + +sub race_solution($time,$distance) { + my $min = ( $time - sqrt( $time**2 - 4 * $distance) ) / 2; + my $max = ( $time + sqrt( $time**2 - 4 * $distance) ) / 2; + + $min = int($min)+1; + $max = ($max == int $max)?$max-1:int $max; + + warn "$min - $max"; + return $max-$min+1; +} + +sub solution_1 ($input) { + product map { race_solution(@$_)} parse_file($input); +} + +1; diff --git a/2023/06/Part2.pm b/2023/06/Part2.pm new file mode 100644 index 0000000..c907947 --- /dev/null +++ b/2023/06/Part2.pm @@ -0,0 +1,14 @@ +use 5.38.0; + +package Part2; + +use Part1; + +use List::AllUtils qw/ /; + + +sub solution_2 ($input) { + ...; +} + +1; diff --git a/2023/06/benchmark.pl b/2023/06/benchmark.pl new file mode 100644 index 0000000..fcf3e70 --- /dev/null +++ b/2023/06/benchmark.pl @@ -0,0 +1,41 @@ +use 5.38.0; + +use Benchmark ':hireswallclock'; +use Path::Tiny; +use JSON qw/ to_json /; +use DateTime; + +use Part1; +use Part2; + +my $day = path('.')->absolute->basename =~ s/^0//r; +my $year = path('.')->absolute->parent->basename; + +my @parts = ( + { part => 1, sub => \&Part1::solution_1, expected => 'TODO' }, + { part => 2, sub => \&Part2::solution_2, expected => 'TODO' }, +); + +my $input = path('./input')->slurp; + +for my $part (@parts) { + my $res = Benchmark::countit( + 10, + sub { + $part->{sub}->($input) == $part->{expected} or die; + } + ); + + my $result = { + day => $day, + year => $year, + + #variant => '', + language => 'perl', + part => $part->{part}, + time => $res->cpu_a / $res->iters, + timestamp => DateTime->now->iso8601, + }; + say to_json $result; +} + diff --git a/2023/06/example b/2023/06/example new file mode 100644 index 0000000..28f5ae9 --- /dev/null +++ b/2023/06/example @@ -0,0 +1,2 @@ +Time: 7 15 30 +Distance: 9 40 200 diff --git a/2023/06/part1.t b/2023/06/part1.t new file mode 100644 index 0000000..4e92326 --- /dev/null +++ b/2023/06/part1.t @@ -0,0 +1,20 @@ +use 5.38.0; + +use Test2::V0; + +use Path::Tiny; + +use Part1; + +my $input = path('input')->slurp; +my $example = path('example')->slurp; + +is [ map { Part1::race_solution(@$_)} Part1::parse_file($example)] + => [4,8,9]; + +is Part1::solution_1($example) => 288; + +cmp_ok Part1::solution_1($input), '<' ,230202; +is Part1::solution_1($input) => 'TODO'; + +done_testing; diff --git a/2023/06/part2.t b/2023/06/part2.t new file mode 100644 index 0000000..0401ccc --- /dev/null +++ b/2023/06/part2.t @@ -0,0 +1,13 @@ +use 5.38.0; + +use Test2::V0; + +use Path::Tiny; + +use Part2; + +my $input = path('input')->slurp; + +is Part2::solution_2($input) => 'TODO'; + +done_testing; diff --git a/2023/06/solutions.yml b/2023/06/solutions.yml new file mode 100644 index 0000000..7f8aaa0 --- /dev/null +++ b/2023/06/solutions.yml @@ -0,0 +1,2 @@ +1: 211904 +2: TODO From 5fedf5b0acc8ba121fb08838f03f80a31e73f045 Mon Sep 17 00:00:00 2001 From: Yanick Champoux Date: Wed, 6 Dec 2023 11:07:57 -0500 Subject: [PATCH 2/7] part 2 --- 2023/06/Part1.pm | 1 - 2023/06/Part2.pm | 7 +++++-- 2023/06/benchmark.pl | 8 ++++++-- 2023/06/part1.t | 4 +++- 2023/06/part2.t | 6 +++++- 2023/06/solutions.yml | 2 +- 2023/benchmark.json | 3 +++ 7 files changed, 23 insertions(+), 8 deletions(-) diff --git a/2023/06/Part1.pm b/2023/06/Part1.pm index 4613141..48fd67a 100644 --- a/2023/06/Part1.pm +++ b/2023/06/Part1.pm @@ -20,7 +20,6 @@ sub race_solution($time,$distance) { $min = int($min)+1; $max = ($max == int $max)?$max-1:int $max; - warn "$min - $max"; return $max-$min+1; } diff --git a/2023/06/Part2.pm b/2023/06/Part2.pm index c907947..4147085 100644 --- a/2023/06/Part2.pm +++ b/2023/06/Part2.pm @@ -4,11 +4,14 @@ package Part2; use Part1; -use List::AllUtils qw/ /; +use List::AllUtils qw/ product /; +sub parse_file($input) { + map { join '', /(\d+)/g } split "\n", $input; +} sub solution_2 ($input) { - ...; + Part1::race_solution(parse_file($input)); } 1; diff --git a/2023/06/benchmark.pl b/2023/06/benchmark.pl index fcf3e70..9ad9e63 100644 --- a/2023/06/benchmark.pl +++ b/2023/06/benchmark.pl @@ -4,6 +4,7 @@ use Benchmark ':hireswallclock'; use Path::Tiny; use JSON qw/ to_json /; use DateTime; +use File::Serialize; use Part1; use Part2; @@ -11,9 +12,11 @@ use Part2; my $day = path('.')->absolute->basename =~ s/^0//r; my $year = path('.')->absolute->parent->basename; +my $solutions = deserialize_file('solutions.yml'); + my @parts = ( - { part => 1, sub => \&Part1::solution_1, expected => 'TODO' }, - { part => 2, sub => \&Part2::solution_2, expected => 'TODO' }, + { part => 1, sub => \&Part1::solution_1, expected => $solutions->{1} }, + { part => 2, sub => \&Part2::solution_2, expected => $solutions->{2} }, ); my $input = path('./input')->slurp; @@ -34,6 +37,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/06/part1.t b/2023/06/part1.t index 4e92326..5a77e5a 100644 --- a/2023/06/part1.t +++ b/2023/06/part1.t @@ -3,11 +3,13 @@ use 5.38.0; use Test2::V0; use Path::Tiny; +use File::Serialize; use Part1; my $input = path('input')->slurp; my $example = path('example')->slurp; +my $solutions = deserialize_file('solutions.yml'); is [ map { Part1::race_solution(@$_)} Part1::parse_file($example)] => [4,8,9]; @@ -15,6 +17,6 @@ is [ map { Part1::race_solution(@$_)} Part1::parse_file($example)] is Part1::solution_1($example) => 288; cmp_ok Part1::solution_1($input), '<' ,230202; -is Part1::solution_1($input) => 'TODO'; +is Part1::solution_1($input) => $solutions->{1}; done_testing; diff --git a/2023/06/part2.t b/2023/06/part2.t index 0401ccc..d5c7d4a 100644 --- a/2023/06/part2.t +++ b/2023/06/part2.t @@ -3,11 +3,15 @@ use 5.38.0; use Test2::V0; use Path::Tiny; +use File::Serialize; use Part2; my $input = path('input')->slurp; +my $example = path('example')->slurp; +my $solutions = deserialize_file('solutions.yml'); -is Part2::solution_2($input) => 'TODO'; +is Part2::solution_2($example) => 71503; +is Part2::solution_2($input) => $solutions->{2}; done_testing; diff --git a/2023/06/solutions.yml b/2023/06/solutions.yml index 7f8aaa0..3ba62a0 100644 --- a/2023/06/solutions.yml +++ b/2023/06/solutions.yml @@ -1,2 +1,2 @@ 1: 211904 -2: TODO +2: 43364472 diff --git a/2023/benchmark.json b/2023/benchmark.json index c3bb363..e1feac8 100644 --- a/2023/benchmark.json +++ b/2023/benchmark.json @@ -12,3 +12,6 @@ {"day":4,"year":2023,"language":"javascript","part":"2","timestamp":"2023-12-04T15:22:09.052Z","time":0.002291685911610818,"persec":436.3599719025647} {"timestamp":"2023-12-05T23:24:26","persec":1139.15547024952,"year":"2023","day":"5","part":1,"language":"perl","time":0.000877843302443134} {"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} + From 90b352362ac3158fb59cf185ef387069002029b4 Mon Sep 17 00:00:00 2001 From: Yanick Champoux Date: Thu, 7 Dec 2023 10:01:29 -0500 Subject: [PATCH 3/7] starting day 7 --- 2023/07/Part1.pm | 11 ++++++ 2023/07/Part2.pm | 14 +++++++ 2023/07/benchmark.pl | 43 +++++++++++++++++++++ 2023/07/part1.t | 13 +++++++ 2023/07/part2.t | 13 +++++++ 2023/07/solutions.yml | 2 + 2023/preset/day/templates/perl/benchmark.pl | 6 ++- 7 files changed, 100 insertions(+), 2 deletions(-) create mode 100644 2023/07/Part1.pm create mode 100644 2023/07/Part2.pm create mode 100644 2023/07/benchmark.pl create mode 100644 2023/07/part1.t create mode 100644 2023/07/part2.t create mode 100644 2023/07/solutions.yml diff --git a/2023/07/Part1.pm b/2023/07/Part1.pm new file mode 100644 index 0000000..c9b4e65 --- /dev/null +++ b/2023/07/Part1.pm @@ -0,0 +1,11 @@ +use 5.38.0; + +package Part1; + +use List::AllUtils qw/ /; + +sub solution_1 ($input) { + ...; +} + +1; diff --git a/2023/07/Part2.pm b/2023/07/Part2.pm new file mode 100644 index 0000000..c907947 --- /dev/null +++ b/2023/07/Part2.pm @@ -0,0 +1,14 @@ +use 5.38.0; + +package Part2; + +use Part1; + +use List::AllUtils qw/ /; + + +sub solution_2 ($input) { + ...; +} + +1; diff --git a/2023/07/benchmark.pl b/2023/07/benchmark.pl new file mode 100644 index 0000000..36ab17c --- /dev/null +++ b/2023/07/benchmark.pl @@ -0,0 +1,43 @@ +use 5.38.0; + +use Benchmark ':hireswallclock'; +use Path::Tiny; +use JSON qw/ to_json /; +use DateTime; +use File::Serialize; + +use Part1; +use Part2; + +my $day = path('.')->absolute->basename =~ s/^0//r; +my $year = path('.')->absolute->parent->basename; +my $solutions = deserialize_file('solutions.yml'); + +my @parts = ( + { part => 1, sub => \&Part1::solution_1, expected => $solutions->{1} }, + { part => 2, sub => \&Part2::solution_2, expected => $solutions->{2} }, +); + +my $input = path('./input')->slurp; + +for my $part (@parts) { + my $res = Benchmark::countit( + 10, + sub { + $part->{sub}->($input) == $part->{expected} or die; + } + ); + + my $result = { + day => $day, + year => $year, + + #variant => '', + language => 'perl', + part => $part->{part}, + time => $res->cpu_a / $res->iters, + timestamp => DateTime->now->iso8601, + }; + say to_json $result; +} + diff --git a/2023/07/part1.t b/2023/07/part1.t new file mode 100644 index 0000000..ae7365e --- /dev/null +++ b/2023/07/part1.t @@ -0,0 +1,13 @@ +use 5.38.0; + +use Test2::V0; + +use Path::Tiny; + +use Part1; + +my $input = path('input')->slurp; + +is Part1::solution_1($input) => 'TODO'; + +done_testing; diff --git a/2023/07/part2.t b/2023/07/part2.t new file mode 100644 index 0000000..0401ccc --- /dev/null +++ b/2023/07/part2.t @@ -0,0 +1,13 @@ +use 5.38.0; + +use Test2::V0; + +use Path::Tiny; + +use Part2; + +my $input = path('input')->slurp; + +is Part2::solution_2($input) => 'TODO'; + +done_testing; diff --git a/2023/07/solutions.yml b/2023/07/solutions.yml new file mode 100644 index 0000000..67055f3 --- /dev/null +++ b/2023/07/solutions.yml @@ -0,0 +1,2 @@ +1: TODO +2: TODO diff --git a/2023/preset/day/templates/perl/benchmark.pl b/2023/preset/day/templates/perl/benchmark.pl index fcf3e70..36ab17c 100644 --- a/2023/preset/day/templates/perl/benchmark.pl +++ b/2023/preset/day/templates/perl/benchmark.pl @@ -4,16 +4,18 @@ use Benchmark ':hireswallclock'; use Path::Tiny; use JSON qw/ to_json /; use DateTime; +use File::Serialize; use Part1; use Part2; my $day = path('.')->absolute->basename =~ s/^0//r; my $year = path('.')->absolute->parent->basename; +my $solutions = deserialize_file('solutions.yml'); my @parts = ( - { part => 1, sub => \&Part1::solution_1, expected => 'TODO' }, - { part => 2, sub => \&Part2::solution_2, expected => 'TODO' }, + { part => 1, sub => \&Part1::solution_1, expected => $solutions->{1} }, + { part => 2, sub => \&Part2::solution_2, expected => $solutions->{2} }, ); my $input = path('./input')->slurp; From 7d9ed03691801acd349c81cd6e28cf735ed5ae5a Mon Sep 17 00:00:00 2001 From: Yanick Champoux Date: Thu, 7 Dec 2023 10:33:30 -0500 Subject: [PATCH 4/7] part 1 --- 2023/07/Part1.pm | 57 +++++++++++++++++++++++++++++++++++++++++-- 2023/07/example | 5 ++++ 2023/07/part1.t | 14 +++++++++++ 2023/07/solutions.yml | 2 +- 4 files changed, 75 insertions(+), 3 deletions(-) create mode 100644 2023/07/example diff --git a/2023/07/Part1.pm b/2023/07/Part1.pm index c9b4e65..5051721 100644 --- a/2023/07/Part1.pm +++ b/2023/07/Part1.pm @@ -2,10 +2,63 @@ use 5.38.0; package Part1; -use List::AllUtils qw/ /; +use List::AllUtils qw/ pairmap sum /; +use List::UtilsBy qw/ sort_by /; + +sub rank_hand(@hand) { + @hand = split '', shift @hand if @hand == 1; + + my %group; + $group{$_}++ for @hand; + + #use DDP; p %group; + + return 7 if 1 == keys %group; + + return 6 if grep { $_ == 4 } values %group; + + return 5 if keys %group == 2 and grep { $_ == 3 } values %group; + + return 4 if grep { $_ == 3 } values %group; + + return 3 if keys %group == 3; + + return 2 if keys %group == 4; + + return 1; +} + +sub handify($str) { + state %map = ( + 'T' => 10, + 'J' => 11, + '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_1 ($input) { - ...; + my @hand_score = sort_by { score($_->[0]->@*) } parse_input($input); + my $rank = 0; + # use DDP; p @hand_score; + return sum map { ++$rank * $_->[1] } @hand_score; } 1; diff --git a/2023/07/example b/2023/07/example new file mode 100644 index 0000000..e3500c3 --- /dev/null +++ b/2023/07/example @@ -0,0 +1,5 @@ +32T3K 765 +T55J5 684 +KK677 28 +KTJJT 220 +QQQJA 483 diff --git a/2023/07/part1.t b/2023/07/part1.t index ae7365e..3f86a4e 100644 --- a/2023/07/part1.t +++ b/2023/07/part1.t @@ -7,7 +7,21 @@ use Path::Tiny; use Part1; my $input = path('input')->slurp; +my $example = path('example')->slurp; +is Part1::rank_hand( 'AAAAA') => 7; +is Part1::rank_hand( 'AA8AA') => 6; +is Part1::rank_hand( '23332') => 5; +is Part1::rank_hand( 'TTT98') => 4; +is Part1::rank_hand( '23432') => 3; +is Part1::rank_hand( 'A23A4') => 2; +is Part1::rank_hand( '23456') => 1; + +is [ Part1::parse_input( '2345A 123') ] => [ +[ [qw/ a b c d m /], 123 ] +]; + +is Part1::solution_1($example) => 6440; is Part1::solution_1($input) => 'TODO'; done_testing; diff --git a/2023/07/solutions.yml b/2023/07/solutions.yml index 67055f3..1f1ab68 100644 --- a/2023/07/solutions.yml +++ b/2023/07/solutions.yml @@ -1,2 +1,2 @@ -1: TODO +1: 250058342 2: TODO From 482ae97ee68b225bac3d536efd404b411e05c375 Mon Sep 17 00:00:00 2001 From: Yanick Champoux Date: Thu, 7 Dec 2023 11:10:22 -0500 Subject: [PATCH 5/7] part 2 --- 2023/07/Part2.pm | 58 +++++++++++++++++++++++++++++++++++++++++-- 2023/07/benchmark.pl | 1 + 2023/07/part2.t | 6 ++++- 2023/07/solutions.yml | 2 +- 2023/benchmark.json | 3 ++- 5 files changed, 65 insertions(+), 5 deletions(-) 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"} From 046cb8f5383981a9862dc1b37698e40c1c5ed898 Mon Sep 17 00:00:00 2001 From: Yanick Champoux Date: Thu, 7 Dec 2023 11:23:53 -0500 Subject: [PATCH 6/7] pretty --- 2023/.gitignore | 1 + 2023/07/Part1.pm | 29 ++++++++++++++++------------- 2023/07/Part2.pm | 32 +++++++++++++++++--------------- 2023/07/benchmark.pl | 6 +++--- 2023/07/part1.t | 22 ++++++++++------------ 2023/07/part2.t | 2 +- 6 files changed, 48 insertions(+), 44 deletions(-) create mode 100644 2023/.gitignore diff --git a/2023/.gitignore b/2023/.gitignore new file mode 100644 index 0000000..751553b --- /dev/null +++ b/2023/.gitignore @@ -0,0 +1 @@ +*.bak diff --git a/2023/07/Part1.pm b/2023/07/Part1.pm index 5051721..d72da20 100644 --- a/2023/07/Part1.pm +++ b/2023/07/Part1.pm @@ -3,9 +3,9 @@ use 5.38.0; package Part1; 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; my %group; @@ -28,35 +28,38 @@ sub rank_hand(@hand) { return 1; } -sub handify($str) { +sub handify ($str) { state %map = ( 'T' => 10, 'J' => 11, 'Q' => 12, '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; } -sub parse_input($input) { - my @lines = split "\n", $input; - my @hand_score = pairmap { - [ handify($a), $b] - } map { split " " } @lines; +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) { +sub score (@hand) { join '', rank_hand(@hand), @hand; } sub solution_1 ($input) { - my @hand_score = sort_by { score($_->[0]->@*) } parse_input($input); - my $rank = 0; + my @hand_score = sort_by { score( $_->[0]->@* ) } parse_input($input); + my $rank = 0; + # use DDP; p @hand_score; return sum map { ++$rank * $_->[1] } @hand_score; } diff --git a/2023/07/Part2.pm b/2023/07/Part2.pm index cc89c80..99c8594 100644 --- a/2023/07/Part2.pm +++ b/2023/07/Part2.pm @@ -5,9 +5,9 @@ package Part2; use Part1; 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; my %group; @@ -17,11 +17,11 @@ sub rank_hand(@hand) { 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; - if( $max + $jokers >= 3 ) { + if ( $max + $jokers >= 3 ) { return 5 if keys %group <= 2; return 4; } @@ -33,35 +33,37 @@ sub rank_hand(@hand) { return 1; } -sub handify($str) { +sub handify ($str) { state %map = ( 'T' => 10, 'J' => 1, 'Q' => 12, '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; } -sub parse_input($input) { - my @lines = split "\n", $input; - my @hand_score = pairmap { - [ handify($a), $b] - } map { split " " } @lines; +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) { +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; + my @hand_score = sort_by { score( $_->[0]->@* ) } parse_input($input); + my $rank = 0; return sum map { ++$rank * $_->[1] } @hand_score; } diff --git a/2023/07/benchmark.pl b/2023/07/benchmark.pl index d0ffeee..6154f18 100644 --- a/2023/07/benchmark.pl +++ b/2023/07/benchmark.pl @@ -9,8 +9,8 @@ use File::Serialize; use Part1; use Part2; -my $day = path('.')->absolute->basename =~ s/^0//r; -my $year = path('.')->absolute->parent->basename; +my $day = path('.')->absolute->basename =~ s/^0//r; +my $year = path('.')->absolute->parent->basename; my $solutions = deserialize_file('solutions.yml'); my @parts = ( @@ -36,7 +36,7 @@ for my $part (@parts) { language => 'perl', part => $part->{part}, time => $res->cpu_a / $res->iters, - persec => $res->iters / $res->cpu_a , + persec => $res->iters / $res->cpu_a, timestamp => DateTime->now->iso8601, }; say to_json $result; diff --git a/2023/07/part1.t b/2023/07/part1.t index 3f86a4e..af95d38 100644 --- a/2023/07/part1.t +++ b/2023/07/part1.t @@ -6,22 +6,20 @@ use Path::Tiny; use Part1; -my $input = path('input')->slurp; +my $input = path('input')->slurp; my $example = path('example')->slurp; -is Part1::rank_hand( 'AAAAA') => 7; -is Part1::rank_hand( 'AA8AA') => 6; -is Part1::rank_hand( '23332') => 5; -is Part1::rank_hand( 'TTT98') => 4; -is Part1::rank_hand( '23432') => 3; -is Part1::rank_hand( 'A23A4') => 2; -is Part1::rank_hand( '23456') => 1; +is Part1::rank_hand('AAAAA') => 7; +is Part1::rank_hand('AA8AA') => 6; +is Part1::rank_hand('23332') => 5; +is Part1::rank_hand('TTT98') => 4; +is Part1::rank_hand('23432') => 3; +is Part1::rank_hand('A23A4') => 2; +is Part1::rank_hand('23456') => 1; -is [ Part1::parse_input( '2345A 123') ] => [ -[ [qw/ a b c d m /], 123 ] -]; +is [ Part1::parse_input('2345A 123') ] => [ [ [qw/ a b c d m /], 123 ] ]; is Part1::solution_1($example) => 6440; -is Part1::solution_1($input) => 'TODO'; +is Part1::solution_1($input) => 'TODO'; done_testing; diff --git a/2023/07/part2.t b/2023/07/part2.t index 34c6180..65499be 100644 --- a/2023/07/part2.t +++ b/2023/07/part2.t @@ -6,7 +6,7 @@ use Path::Tiny; use Part2; -my $input = path('input')->slurp; +my $input = path('input')->slurp; my $example = path('example')->slurp; is Part2::solution_2($example) => 5905; From cbc7a283a31f5bd4fe83f113f4b2db9100b4c9a0 Mon Sep 17 00:00:00 2001 From: Yanick Champoux Date: Thu, 7 Dec 2023 11:30:37 -0500 Subject: [PATCH 7/7] tweaks --- 2023/07/Part1.pm | 27 ++++++++++----------------- 1 file changed, 10 insertions(+), 17 deletions(-) diff --git a/2023/07/Part1.pm b/2023/07/Part1.pm index d72da20..31fd1b3 100644 --- a/2023/07/Part1.pm +++ b/2023/07/Part1.pm @@ -11,15 +11,14 @@ sub rank_hand (@hand) { my %group; $group{$_}++ for @hand; - #use DDP; p %group; - return 7 if 1 == keys %group; return 6 if grep { $_ == 4 } values %group; - return 5 if keys %group == 2 and grep { $_ == 3 } values %group; - - return 4 if grep { $_ == 3 } values %group; + if( grep { $_ == 3 } values %group ) { + return 5 if keys %group == 2; + return 4; + } return 3 if keys %group == 3; @@ -37,19 +36,16 @@ sub handify ($str) { A => 14 ); - my @cards = - map { chr( ord('a') + $_ - 2 ) } map { $map{$_} // $_ } split '', $str; - - return \@cards; + return [ + map { chr( ord('a') + $_ - 2 ) } map { $map{$_} // $_ } split '', $str + ]; } sub parse_input ($input) { - my @lines = split "\n", $input; - my @hand_score = pairmap { + return pairmap { [ handify($a), $b ] } - map { split " " } @lines; - return @hand_score; + map { split " " } split "\n", $input; } sub score (@hand) { @@ -57,11 +53,8 @@ sub score (@hand) { } sub solution_1 ($input) { - my @hand_score = sort_by { score( $_->[0]->@* ) } parse_input($input); my $rank = 0; - - # use DDP; p @hand_score; - return sum map { ++$rank * $_->[1] } @hand_score; + return sum map { ++$rank * $_->[1] } sort_by { score( $_->[0]->@* ) } parse_input($input); } 1;