From 902e83b8ba3ee2c5568441443e0c6c0c5387b49e Mon Sep 17 00:00:00 2001 From: Yanick Champoux Date: Sun, 5 Dec 2021 11:44:39 -0500 Subject: [PATCH] 2021-02 --- 2021/02/part1.mjs | 8 ++++++++ 2021/02/part1.pm | 35 +++++++++++++++++++++++++++++++++++ 2021/02/part2.mjs | 18 ++++++++++++++++++ 2021/02/part2.pm | 27 +++++++++++++++++++++++++++ 2021/02/sample | 6 ++++++ 2021/02/test.mjs | 25 +++++++++++++++++++++++++ 2021/02/test.t | 20 ++++++++++++++++++++ 7 files changed, 139 insertions(+) create mode 100644 2021/02/part1.mjs create mode 100644 2021/02/part1.pm create mode 100644 2021/02/part2.mjs create mode 100644 2021/02/part2.pm create mode 100644 2021/02/sample create mode 100644 2021/02/test.mjs create mode 100644 2021/02/test.t diff --git a/2021/02/part1.mjs b/2021/02/part1.mjs new file mode 100644 index 0000000..1134972 --- /dev/null +++ b/2021/02/part1.mjs @@ -0,0 +1,8 @@ +import fp from "lodash/fp.js"; + +export const solution = fp.flow([ + fp.groupBy(0), + fp.mapValues(fp.map(fp.get(1))), + fp.mapValues(fp.sum), + ({ forward, up, down }) => forward * (down - up), +]); diff --git a/2021/02/part1.pm b/2021/02/part1.pm new file mode 100644 index 0000000..66571f5 --- /dev/null +++ b/2021/02/part1.pm @@ -0,0 +1,35 @@ +package part1; + +use 5.34.0; +use warnings; +use experimental 'signatures'; + +use List::AllUtils qw/sum/; + +sub group_by(@lines) { + my %grouped = (); + + for my $line (@lines) { + my( $action, $move ) = split ' ', $line; + $grouped{$action} //= []; + push $grouped{$action}->@*, $move; + } + + return %grouped; +} + +sub solution(@lines) { + my %grouped = group_by(@lines); + + for my $v (values %grouped) { + $v = sum @$v; + } + + my $depth = $grouped{down} - $grouped{up}; + my $forward = $grouped{forward}; + + return $depth * $forward; + +} + +1; diff --git a/2021/02/part2.mjs b/2021/02/part2.mjs new file mode 100644 index 0000000..f30e1ee --- /dev/null +++ b/2021/02/part2.mjs @@ -0,0 +1,18 @@ +import fp from "lodash/fp.js"; +import u from "updeep"; + +const update = (action, value) => + action === "down" ? u({ aim: fp.add(value) }) + : action === "up" ? u({ aim: fp.add(-value) }) + : u((state) => + u({ x: fp.add(value), depth: fp.add(value * state.aim) }, state) + ); + +export function solution(lines) { + const { x, depth } = lines.reduce( + (accum, line) => update(...line)(accum), + { depth: 0, aim: 0, x: 0 } + ); + + return x * depth; +} diff --git a/2021/02/part2.pm b/2021/02/part2.pm new file mode 100644 index 0000000..9aae8cd --- /dev/null +++ b/2021/02/part2.pm @@ -0,0 +1,27 @@ +package part2; + +use 5.34.0; + +use experimental qw/ signatures switch/; + +sub solution(@lines) { + my( $depth, $aim, $x ); + + for my $line ( @lines ) { + my( $action, $value ) = split ' ', $line; + + given($action) { + $aim+=$value when 'down'; + $aim-=$value when 'up'; + when( 'forward' ) { + $x += $value; + $depth += $aim * $value; + } + } + } + + return $x * $depth; + +} + +1; diff --git a/2021/02/sample b/2021/02/sample new file mode 100644 index 0000000..b7172ac --- /dev/null +++ b/2021/02/sample @@ -0,0 +1,6 @@ +forward 5 +down 5 +forward 8 +up 3 +down 8 +forward 2 diff --git a/2021/02/test.mjs b/2021/02/test.mjs new file mode 100644 index 0000000..a3fa2c8 --- /dev/null +++ b/2021/02/test.mjs @@ -0,0 +1,25 @@ +import tap from "tap"; +import fs from "fs-extra"; + +import * as part1 from "./part1.mjs"; +import * as part2 from "./part2.mjs"; + +const processFile = async (f) => + fs + .readFile(f, "utf8") + .then((x) => x.split("\n")) + .then((lines) => lines.map((l) => l.split(" "))) + .then((lines) => lines.filter( ([action]) => action ).map((l) => [l[0], parseInt(l[1])])); + +const sample = processFile("sample"); +const input = processFile("input"); + +tap.test("part1", async (t) => { + t.equal(part1.solution(await sample), 150); + t.equal(part1.solution(await input), 2091984); +}); + +tap.test("part2", async (t) => { + t.equal(part2.solution(await sample), 900); + t.equal(part2.solution(await input), 2086261056); +}); diff --git a/2021/02/test.t b/2021/02/test.t new file mode 100644 index 0000000..fb906fc --- /dev/null +++ b/2021/02/test.t @@ -0,0 +1,20 @@ +use 5.34.0; + +use Test2::V0; +use Path::Tiny; + +require './part1.pm'; +require './part2.pm'; + +my @sample = path('sample')->lines; +my @input = path('input')->lines; + +subtest part1 => sub { + is part1::solution(@sample) => 150; + is part1::solution(@input) => 2091984; +}; + +subtest part2 => sub { + is part2::solution(@sample ) => 900; + is part2::solution(@input) => 2086261056; +};