diff --git a/2023/08/Part1.pm b/2023/08/Part1.pm new file mode 100644 index 0000000..2b58001 --- /dev/null +++ b/2023/08/Part1.pm @@ -0,0 +1,43 @@ +use 5.38.0; + +package Part1; + +use List::AllUtils qw/ /; + +sub parse_input($input) { + my ( $directions, undef, @nodes ) = split "\n", $input; + + $directions = [ split "", $directions =~ s/R/1/gr =~ s/L/0/gr ]; + + my %nodes; + + for(@nodes) { + my @n = /([A-Z]+)/g; + $nodes{ shift @n } = \@n; + } + + return { + directions => $directions, + nodes => \%nodes }; +} + +sub solution_1 ($input) { + my $p = parse_input($input); + my @directions = $p->{directions}->@*; + my %nodes = $p->{nodes}->%*; + + my $visited = 0; + my $next_index = 0; + my $current = 'AAA'; + + while( $current ne 'ZZZ') { + $visited++; + + $current = $nodes{$current}->[ $directions[$next_index++ % @directions ] ]; + } + + return $visited; + +} + +1; diff --git a/2023/08/Part2.pm b/2023/08/Part2.pm new file mode 100644 index 0000000..c907947 --- /dev/null +++ b/2023/08/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/08/benchmark.pl b/2023/08/benchmark.pl new file mode 100644 index 0000000..36ab17c --- /dev/null +++ b/2023/08/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/08/example b/2023/08/example new file mode 100644 index 0000000..9029a1b --- /dev/null +++ b/2023/08/example @@ -0,0 +1,9 @@ +RL + +AAA = (BBB, CCC) +BBB = (DDD, EEE) +CCC = (ZZZ, GGG) +DDD = (DDD, DDD) +EEE = (EEE, EEE) +GGG = (GGG, GGG) +ZZZ = (ZZZ, ZZZ) diff --git a/2023/08/part1.t b/2023/08/part1.t new file mode 100644 index 0000000..4168282 --- /dev/null +++ b/2023/08/part1.t @@ -0,0 +1,37 @@ +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')->%*; + +my $parsed = Part1::parse_input($example); + +use DDP; p $parsed; + +is $parsed->{directions} => [1,0]; +is $parsed->{nodes}{AAA} => [ qw/ BBB CCC /]; + + is Part1::solution_1($example) => 2; + is Part1::solution_1(<<'END') => 6; +LLR + +AAA = (BBB, BBB) +BBB = (AAA, ZZZ) +ZZZ = (ZZZ, ZZZ) +END + + SKIP: { + # skip "not there yet" if $solutions{1} eq 'TODO'; + is Part1::solution_1($input) => $solutions{1}; +} + + + +done_testing; diff --git a/2023/08/part2.t b/2023/08/part2.t new file mode 100644 index 0000000..0401ccc --- /dev/null +++ b/2023/08/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/08/solutions.yml b/2023/08/solutions.yml new file mode 100644 index 0000000..b7e185a --- /dev/null +++ b/2023/08/solutions.yml @@ -0,0 +1,2 @@ +1: 19631 +2: TODO