part 1
This commit is contained in:
parent
9608209e8c
commit
b1cf1719a3
43
2023/08/Part1.pm
Normal file
43
2023/08/Part1.pm
Normal file
@ -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;
|
14
2023/08/Part2.pm
Normal file
14
2023/08/Part2.pm
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
use 5.38.0;
|
||||||
|
|
||||||
|
package Part2;
|
||||||
|
|
||||||
|
use Part1;
|
||||||
|
|
||||||
|
use List::AllUtils qw/ /;
|
||||||
|
|
||||||
|
|
||||||
|
sub solution_2 ($input) {
|
||||||
|
...;
|
||||||
|
}
|
||||||
|
|
||||||
|
1;
|
43
2023/08/benchmark.pl
Normal file
43
2023/08/benchmark.pl
Normal file
@ -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;
|
||||||
|
}
|
||||||
|
|
9
2023/08/example
Normal file
9
2023/08/example
Normal file
@ -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)
|
37
2023/08/part1.t
Normal file
37
2023/08/part1.t
Normal file
@ -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;
|
13
2023/08/part2.t
Normal file
13
2023/08/part2.t
Normal file
@ -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;
|
2
2023/08/solutions.yml
Normal file
2
2023/08/solutions.yml
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
1: 19631
|
||||||
|
2: TODO
|
Loading…
Reference in New Issue
Block a user