diff --git a/2021/10/part1.mjs b/2021/10/part1.mjs new file mode 100644 index 0000000..adb6152 --- /dev/null +++ b/2021/10/part1.mjs @@ -0,0 +1,46 @@ +import fs from "fs-extra"; +import fp from "lodash/fp.js"; +import _ from "lodash"; + +export const processInput = (file) => fs.readFile(file,'utf8').then( + content => content.split("\n").filter(x=>x).map( + line => line.split('') + ) +); + +export const closing = { + '{':'}', + '<': ">", + '(': ')', + '[': ']', +}; + +function firstIllegalCharacter(line) { + const stack = []; + + for ( const c of line ) { + if( closing[c] ) { + stack.push(closing[c]); + } else { + if(c !== stack.pop()) return c; + } + } + + return ''; + +} + +export function solution(lines) { + const points = { + ')': 3, + ']': 57, + '}': 1197, + '>': 25137, + } + + return _.sum( + lines.map( firstIllegalCharacter ).map( + c => points[c] || 0 + ) + ) +} diff --git a/2021/10/part2.mjs b/2021/10/part2.mjs new file mode 100644 index 0000000..d0003f6 --- /dev/null +++ b/2021/10/part2.mjs @@ -0,0 +1,42 @@ +import fs from "fs-extra"; +import fp from "lodash/fp.js"; +import _ from "lodash"; + +import * as p1 from "./part1.mjs"; + +function completionString(line) { + const stack = []; + + for (const c of line) { + if (p1.closing[c]) { + stack.unshift(p1.closing[c]); + } else if (c !== stack.shift()) { + return; + } + } + + return stack; +} + +export function linesScore(lines) { + lines = lines.map(completionString).filter((x) => x); + + const points = { + ")": 1, + "]": 2, + "}": 3, + ">": 4, + }; + + const lineScore = (line) => line.reduce((a, b) => 5 * a + points[b], 0); + + return lines.map(lineScore); +} + +export function solution(lines) { + const scores = linesScore(lines); + + scores.sort((a, b) => (a < b ? -1 : 1)); + + return scores[(scores.length - 1) / 2]; +} diff --git a/2021/10/sample b/2021/10/sample new file mode 100644 index 0000000..b1518d9 --- /dev/null +++ b/2021/10/sample @@ -0,0 +1,10 @@ +[({(<(())[]>[[{[]{<()<>> +[(()[<>])]({[<{<<[]>>( +{([(<{}[<>[]}>{[]{[(<()> +(((({<>}<{<{<>}{[]{[]{} +[[<[([]))<([[{}[[()]]] +[{[{({}]{}}([{[{{{}}([] +{<[[]]>}<{[{[{[]{()[[[] +[<(<(<(<{}))><([]([]() +<{([([[(<>()){}]>(<<{{ +<{([{{}}[<[[[<>{}]]]>[]] diff --git a/2021/10/test.mjs b/2021/10/test.mjs new file mode 100644 index 0000000..cc49669 --- /dev/null +++ b/2021/10/test.mjs @@ -0,0 +1,23 @@ +// https://adventofcode.com/2021/day/10 + +import tap from "tap"; +import fs from "fs-extra"; + +import * as p1 from "./part1.mjs"; +import * as p2 from "./part2.mjs"; + +const sample = p1.processInput('sample'); +const input = p1.processInput('input'); + +tap.test("part1", async (t) => { + t.equal(p1.solution(await sample), 26397); + t.equal(p1.solution(await input), 311949); +}); + +tap.test("part2", async (t) => { + t.match(p2.linesScore(await sample), [ + 288957, 5566, 1480781, 995444, 294 + ]); + t.equal(p2.solution(await sample), 288957); + t.equal(p2.solution(await input), 3042730309); +}); diff --git a/2021/_templates/day/new/part1.mjs.t b/2021/_templates/day/new/part1.mjs.t new file mode 100644 index 0000000..7260703 --- /dev/null +++ b/2021/_templates/day/new/part1.mjs.t @@ -0,0 +1,11 @@ +--- +to: '<%= day %>/part1.mjs' +--- +import fs from "fs-extra"; +import fp from "lodash/fp.js"; +import _ from "lodash"; + +export const processInput = (input) => input; + +export function solution(input) { +} diff --git a/2021/_templates/day/new/part1.pm.t b/2021/_templates/day/new/part1.pm.t deleted file mode 100644 index 296e081..0000000 --- a/2021/_templates/day/new/part1.pm.t +++ /dev/null @@ -1,15 +0,0 @@ ---- -to: '<%= day %>/part1.pm' ---- -package part1; - -use 5.34.0; -use warnings; -use experimental 'signatures'; - -use List::AllUtils qw/ /; - -sub solution() { -} - -1; diff --git a/2021/_templates/day/new/part2.mjs.t b/2021/_templates/day/new/part2.mjs.t new file mode 100644 index 0000000..42c54cc --- /dev/null +++ b/2021/_templates/day/new/part2.mjs.t @@ -0,0 +1,11 @@ +--- +to: '<%= day %>/part2.mjs' +--- +import fs from "fs-extra"; +import fp from "lodash/fp.js"; +import _ from "lodash"; + +import * as p1 from './part1.mjs'; + +export function solution(input) { +} diff --git a/2021/_templates/day/new/part2.pm.t b/2021/_templates/day/new/part2.pm.t deleted file mode 100644 index ee431a4..0000000 --- a/2021/_templates/day/new/part2.pm.t +++ /dev/null @@ -1,19 +0,0 @@ ---- -to: '<%= day %>/part2.pm' ---- -package part2; - -use 5.20.0; -use warnings; -use experimental 'signatures'; - -use List::AllUtils qw/ /; - -require './part1.pm'; - -use experimental qw/ signatures postderef /; - -sub solution() { -} - -1; diff --git a/2021/_templates/day/new/test.mjs.t b/2021/_templates/day/new/test.mjs.t new file mode 100644 index 0000000..ad7240b --- /dev/null +++ b/2021/_templates/day/new/test.mjs.t @@ -0,0 +1,23 @@ +--- +to: '<%= day %>/test.mjs' +--- +// https://adventofcode.com/2021/day/<%= day %> + +import tap from "tap"; +import fs from "fs-extra"; + +import * as p1 from "./part1.mjs"; +import * as p2 from "./part2.mjs"; + +const sample = p1.processInput('sample'); +const input = p1.processInput('input'); + +tap.test("part1", async (t) => { + t.equal(p1.solution(await sample), 0); +// t.equal(p1.solution(await input), 0); +}); + +tap.test("part2", async (t) => { + // t.equal(p2.solution(await sample), 0); + // t.equal(p2.solution(await input), 0); +}); diff --git a/2021/_templates/day/new/tests.t b/2021/_templates/day/new/tests.t deleted file mode 100644 index 532d04b..0000000 --- a/2021/_templates/day/new/tests.t +++ /dev/null @@ -1,20 +0,0 @@ ---- -to: '<%= day %>/test.t' ---- -use 5.34.0; - -use Test2::V0; -use Path::Tiny; - -require './part1.pm'; -require './part2.pm'; - -subtest part1 => sub { - my $todo = todo 'TODO'; - is part1::solution( ) => 'TODO'; -}; - -subtest part2 => sub { - my $todo = todo 'TODO'; - is part2::solution( ) => 'TODO'; -};