diff --git a/2023/02/Part1.pm b/2023/02/Part1.pm new file mode 100644 index 0000000..9186d54 --- /dev/null +++ b/2023/02/Part1.pm @@ -0,0 +1,25 @@ +use 5.38.0; + +package Part1; + +use List::AllUtils qw/ max sum /; + +sub parse_line ($line) { + my %data; + $line =~ /Game (\d+):/; + $data{game} = $1; + + $data{$_} = max $line =~ /(\d+) $_/g for qw/ red green blue /; + + return \%data; +} + +sub solution_1 ($input) { + sum + map { $_->{game} } + grep { $_->{red} <= 12 and $_->{blue} <= 14 and $_->{green} <= 13 } + map { parse_line($_) } + split "\n", $input; +} + +1; diff --git a/2023/02/Part2.pm b/2023/02/Part2.pm new file mode 100644 index 0000000..b5d60e1 --- /dev/null +++ b/2023/02/Part2.pm @@ -0,0 +1,16 @@ +use 5.38.0; + +package Part2; + +use Part1; + +use List::AllUtils qw/ min product sum /; + +sub solution_2 ($input) { + sum + map { product $_->@{qw/ red blue green /} } + map { Part1::parse_line($_) } + split "\n", $input; +} + +1; diff --git a/2023/02/benchmark.pl b/2023/02/benchmark.pl new file mode 100644 index 0000000..c1e2fdf --- /dev/null +++ b/2023/02/benchmark.pl @@ -0,0 +1,45 @@ +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 $solutions = deserialize_file('solutions.yml'); + +my $day = path('.')->absolute->basename =~ s/^0//r; +my $year = path('.')->absolute->parent->basename; + +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 => 'v2', + language => 'perl', + part => $part->{part}, + time => $res->cpu_a / $res->iters, + parsec =>$res->iters/$res->cpu_a , + timestamp => DateTime->now->iso8601, + }; + say to_json $result; +} + diff --git a/2023/02/part1.t b/2023/02/part1.t new file mode 100644 index 0000000..a9a0f8f --- /dev/null +++ b/2023/02/part1.t @@ -0,0 +1,29 @@ +use 5.38.0; + +use Test2::V0; + +use Path::Tiny; + +use Part1; + +is Part1::parse_line( + "Game 1: 3 blue, 4 red; 1 red, 2 green, 6 blue; 2 green") => +{ + game => 1, + blue => 6, + red => 4, + green => 2 + }; + +is Part1::solution_1( <<'END' ) => 8; +Game 1: 3 blue, 4 red; 1 red, 2 green, 6 blue; 2 green +Game 2: 1 blue, 2 green; 3 green, 4 blue, 1 red; 1 green, 1 blue +Game 3: 8 green, 6 blue, 20 red; 5 blue, 4 red, 13 green; 5 green, 1 red +Game 4: 1 green, 3 red, 6 blue; 3 green, 6 red; 3 green, 15 blue, 14 red +Game 5: 6 red, 1 blue, 3 green; 2 blue, 1 red, 2 green +END + +my $input = path('input')->slurp; + +is Part1::solution_1($input) => 1853; + +done_testing(); diff --git a/2023/02/part2.t b/2023/02/part2.t new file mode 100644 index 0000000..f8552e6 --- /dev/null +++ b/2023/02/part2.t @@ -0,0 +1,20 @@ +use 5.38.0; + +use Test2::V0; + +use Path::Tiny; + +use Part2; + +is Part2::solution_2( <<'END' ) => 2286; +Game 1: 3 blue, 4 red; 1 red, 2 green, 6 blue; 2 green +Game 2: 1 blue, 2 green; 3 green, 4 blue, 1 red; 1 green, 1 blue +Game 3: 8 green, 6 blue, 20 red; 5 blue, 4 red, 13 green; 5 green, 1 red +Game 4: 1 green, 3 red, 6 blue; 3 green, 6 red; 3 green, 15 blue, 14 red +Game 5: 6 red, 1 blue, 3 green; 2 blue, 1 red, 2 green +END + +my $input = path('input')->slurp; + +cmp_ok Part2::solution_2($input), ">", 1720; +is Part2::solution_2($input) => 72706; diff --git a/2023/02/solutions.yml b/2023/02/solutions.yml new file mode 100644 index 0000000..51c2a15 --- /dev/null +++ b/2023/02/solutions.yml @@ -0,0 +1,2 @@ +1: 1853 +2: 72706 diff --git a/2023/benchmark.json b/2023/benchmark.json index bdd5f2b..5616bda 100644 --- a/2023/benchmark.json +++ b/2023/benchmark.json @@ -1,4 +1,8 @@ -{"language":"perl","time":0.00189813978688821,"part":1,"day":1,"year":2023,"timestamp":"2023-12-01T17:35:46"} -{"language":"perl","part":2,"time":0.00721379310344828,"day":1,"year":2023,"timestamp":"2023-12-01T17:35:58"} -{"day":1,"year":2023,"language":"javascript","part":"1","timestamp":"2023-12-01T20:55:40.986Z","time":0.0007267522645031297} -{"day":1,"year":2023,"language":"javascript","part":"2","timestamp":"2023-12-01T20:55:40.989Z","time":0.004363576172638605} +{"language":"perl","time":0.00189813978688821,"part":1,"day":1,"year":2023,"timestamp":"2023-12-01T17:35:46","persec":526.8315889628915} +{"language":"perl","part":2,"time":0.00721379310344828,"day":1,"year":2023,"timestamp":"2023-12-01T17:35:58","persec":138.62332695984696} +{"day":1,"year":2023,"language":"javascript","part":"1","timestamp":"2023-12-01T20:55:40.986Z","time":0.0007267522645031297,"persec":1375.9847046141451} +{"day":1,"year":2023,"language":"javascript","part":"2","timestamp":"2023-12-01T20:55:40.989Z","time":0.004363576172638605,"persec":229.1698277826353} +{"language":"perl","timestamp":"2023-12-02T16:40:42","part":1,"day":"2","persec":297.067171239357,"year":"2023","time":0.00336624203821656} +{"language":"perl","timestamp":"2023-12-02T16:40:55","part":2,"day":"2","time":0.00338658146964856,"year":"2023","persec":295.283018867925} +{"timestamp":"2023-12-02T18:29:20","day":"2","part":1,"variant":"v2","year":"2023","time":0.00388473053892216,"language":"perl","parsec":257.418111753372} +{"day":"2","timestamp":"2023-12-02T18:29:32","part":2,"year":"2023","variant":"v2","parsec":258.117195004803,"language":"perl","time":0.00387420915519166} diff --git a/2023/preset/day/.gitignore b/2023/preset/day/.gitignore new file mode 100644 index 0000000..3c3629e --- /dev/null +++ b/2023/preset/day/.gitignore @@ -0,0 +1 @@ +node_modules diff --git a/2023/preset/day/README.md b/2023/preset/day/README.md new file mode 100644 index 0000000..c513b01 --- /dev/null +++ b/2023/preset/day/README.md @@ -0,0 +1,19 @@ +

+
+ + Logo of Preset + +
+

+ +

day

+
npx @preset/cli apply username//home/yanick/work/javascript/adventofcode/2023/preset/day
+ +
+ +
+ This preset was made by Yanick Champoux. +
+
+ Learn more +
diff --git a/2023/preset/day/package.json b/2023/preset/day/package.json new file mode 100644 index 0000000..850e04c --- /dev/null +++ b/2023/preset/day/package.json @@ -0,0 +1,6 @@ +{ + "private": true, + "author": "Yanick Champoux ", + "license": "MIT", + "preset": "preset.ts" +} diff --git a/2023/preset/day/preset.ts b/2023/preset/day/preset.ts new file mode 100644 index 0000000..163677f --- /dev/null +++ b/2023/preset/day/preset.ts @@ -0,0 +1,14 @@ +export default definePreset({ + name: 'day', + options: { + perl: true, + }, + handler: async(context) => { + if( context.options.perl ) { + await extractTemplates({ + from: 'perl', whenConflict: 'skip' + }) + } + // ... + }, +}) diff --git a/2023/preset/day/templates/.gitkeep b/2023/preset/day/templates/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/2023/preset/day/templates/perl/Part1.pm b/2023/preset/day/templates/perl/Part1.pm new file mode 100644 index 0000000..c9b4e65 --- /dev/null +++ b/2023/preset/day/templates/perl/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/preset/day/templates/perl/Part2.pm b/2023/preset/day/templates/perl/Part2.pm new file mode 100644 index 0000000..c907947 --- /dev/null +++ b/2023/preset/day/templates/perl/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/preset/day/templates/perl/benchmark.pl b/2023/preset/day/templates/perl/benchmark.pl new file mode 100644 index 0000000..a01b63b --- /dev/null +++ b/2023/preset/day/templates/perl/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->dir->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/preset/day/templates/perl/part1.t b/2023/preset/day/templates/perl/part1.t new file mode 100644 index 0000000..d09f96c --- /dev/null +++ b/2023/preset/day/templates/perl/part1.t @@ -0,0 +1,11 @@ +use 5.38.0; + +use Test2::V0; + +use Path::Tiny; + +use Part1; + +my $input = path('input')->slurp; + +is Part1::solution_1($input) => 'TODO'; diff --git a/2023/preset/day/templates/perl/part2.t b/2023/preset/day/templates/perl/part2.t new file mode 100644 index 0000000..41be8ed --- /dev/null +++ b/2023/preset/day/templates/perl/part2.t @@ -0,0 +1,11 @@ +use 5.38.0; + +use Test2::V0; + +use Path::Tiny; + +use Part2; + +my $input = path('input')->slurp; + +is Part2::solution_2($input) => 'TODO'; diff --git a/2023/preset/day/tsconfig.json b/2023/preset/day/tsconfig.json new file mode 100644 index 0000000..5dcab8a --- /dev/null +++ b/2023/preset/day/tsconfig.json @@ -0,0 +1,18 @@ +{ + "compilerOptions": { + "module": "esnext", + "baseUrl": ".", + "target": "es2016", + "lib": ["esnext"], + "esModuleInterop": true, + "skipLibCheck": true, + "moduleResolution": "node", + "resolveJsonModule": true, + "types": ["node", "@preset/core/globals"] + }, + "include": [ + "./*.ts", + "./src/**/*.ts" + ], + "exclude": ["templates", "node_modules"] +}