diff --git a/2021/03/part1.mjs b/2021/03/part1.mjs new file mode 100644 index 0000000..e34d64d --- /dev/null +++ b/2021/03/part1.mjs @@ -0,0 +1,25 @@ +import fs from "fs-extra"; +import fp from "lodash/fp.js"; +import _ from "lodash"; + +export const processFile = async (f) => + fs + .readFile(f, "utf8") + .then((x) => x.split("\n").filter((x) => x)) + .then((lines) => + lines.map((l) => l.split("").map((x) => parseInt(x))) + ); + +const mostCommon = (numbers) => (_.sum(numbers) * 2 > numbers.length ? 1 : 0); + +export const toDecimal = (numbers) => numbers.reduce((a, x) => a * 2 + x, 0); + +export const solution = (entries) => { + const groups = _.zip(...entries).map(mostCommon); + + const gamma = toDecimal(groups); + + const epsilon = toDecimal(groups.map((x) => 1 - x)); + + return gamma * epsilon; +}; diff --git a/2021/03/part2.mjs b/2021/03/part2.mjs new file mode 100644 index 0000000..6419a66 --- /dev/null +++ b/2021/03/part2.mjs @@ -0,0 +1,27 @@ +import fp from "lodash/fp.js"; +import _ from "lodash"; +import u from "updeep"; + +import { toDecimal } from "./part1.mjs"; + +function findNumber(entries, index, most) { + // which number to filter on + const mostSeen = + _.sum(entries.map((e) => e[index])) * 2 >= entries.length ? 1 : 0; + + const filter = most ? mostSeen : 1 - mostSeen; + + const filtered = entries.filter((e) => e[index] === filter); + + if (filtered.length === 1) return filtered[0]; + + return findNumber(filtered, index + 1, most); +} + +export const solution = (entries) => { + const oxyGenerator = toDecimal(findNumber(entries, 0, true)); + + const scrubber = toDecimal(findNumber(entries, 0, false)); + + return oxyGenerator * scrubber; +}; diff --git a/2021/03/sample b/2021/03/sample new file mode 100644 index 0000000..a6366a8 --- /dev/null +++ b/2021/03/sample @@ -0,0 +1,12 @@ +00100 +11110 +10110 +10111 +10101 +01111 +00111 +11100 +10000 +11001 +00010 +01010 diff --git a/2021/03/test.mjs b/2021/03/test.mjs new file mode 100644 index 0000000..e9099ee --- /dev/null +++ b/2021/03/test.mjs @@ -0,0 +1,18 @@ +import tap from "tap"; + +import * as p1 from "./part1.mjs"; +import * as p2 from "./part2.mjs"; + + +const sample = p1.processFile("sample"); +const input = p1.processFile("input"); + +tap.test("part1", async (t) => { + t.equal(p1.solution(await sample), 198); + t.equal(p1.solution(await input), 3813416 ); +}); + +tap.test("part2", async (t) => { + t.equal(p2.solution(await sample), 230); + t.equal(p2.solution(await input), 2990784); +});