diff --git a/2021/08/part1.mjs b/2021/08/part1.mjs new file mode 100644 index 0000000..b68a952 --- /dev/null +++ b/2021/08/part1.mjs @@ -0,0 +1,34 @@ +import fs from "fs-extra"; +import fp from "lodash/fp.js"; +import _ from "lodash"; + +export const digits = { + 0: 'abcefg', // 6 + 1: 'cf', // 2 + 2: 'acdeg', // 5 + 3: 'acdfg', // 5 + 4: 'bcdf', // 4 + 5: 'abdfg', // 5 + 6: 'abdefg', // 6 + 7: 'acf', // 3 + 8: 'abcdefg',// 7 + 9: 'abcdfg', // 6 +} + +export const processInput = (lines) => { + return lines.split("\n").filter(x=>x).map( line => { + let [ input, output ] = line.split(' | ').map( + x => x.split(' ').map( x => x.split('').sort() ) + ); + + return {input, output}; + } + ) +}; + +/** @return {number} */ +export function solution(lines) { + return lines.map(fp.get('output')).flat().filter( + x => [2,4,3,7].includes(x.length ) + ).length +} diff --git a/2021/08/part2.mjs b/2021/08/part2.mjs new file mode 100644 index 0000000..44b32ab --- /dev/null +++ b/2021/08/part2.mjs @@ -0,0 +1,83 @@ +import fp from "lodash/fp.js"; +import _ from "lodash"; + +import * as p1 from "./part1.mjs"; + +function decodedDigits(mapping) { + const s = fp.invert(mapping); + + return _.flow([ + fp.invert, + fp.mapKeys((k) => + k + .split("") + .map((l) => s[l]) + .join("") + ), + fp.mapKeys((k) => k.split("").sort().join("")), + ])(p1.digits); +} + +function guess(unknowns, guessed = {}, inputs) { + const [next] = Object.keys(unknowns); + + if (!next) return guessed; + + for (const p of unknowns[next]) { + let newUnknowns = fp.mapValues( + (s) => s.filter((x) => x !== p), + fp.omit(next, unknowns) + ); + + if (Object.values(newUnknowns).some((s) => s.size === 0)) continue; + + const r = guess(newUnknowns, { ...guessed, [next]: p }, inputs); + + if (!r) continue; + + const solution = decodedDigits(r); + + if (inputs.every((i) => solution.hasOwnProperty(i.join("")))) + return r; + } +} + +export function findMapping(input) { + const values = "abcdefg".split(""); + + let possibility = Object.fromEntries(values.map((v) => [v, values])); + + for (const seq of input) { + const p = Object.values(p1.digits) + .filter((d) => d.length === seq.length) + .join("") + .split(""); + + for (const l of seq) { + possibility[l] = _.intersection(possibility[l], p); + } + } + + // feel cute, might delete later + const one = input.find((i) => i.length === 2); + const seven = input.find((i) => i.length === 3); + const [a] = seven.filter((x) => !one.includes(x)); + + possibility = fp.mapValues(fp.reject("a"), possibility); + + possibility[a] = ["a"]; + + return guess(possibility, {}, input); +} + +export function decodedOutput({ input, output }) { + const mapping = findMapping([...input, ...output]); + + const digits = decodedDigits(mapping); + + return parseInt(output.map((e) => digits[e.join("")]).join("")); +} + +export function solution(input) { + return _.sum(input.map(decodedOutput)); +} diff --git a/2021/08/sample b/2021/08/sample new file mode 100644 index 0000000..c9f629b --- /dev/null +++ b/2021/08/sample @@ -0,0 +1,10 @@ +be cfbegad cbdgef fgaecd cgeb fdcge agebfd fecdb fabcd edb | fdgacbe cefdb cefbgd gcbe +edbfga begcd cbg gc gcadebf fbgde acbgfd abcde gfcbed gfec | fcgedb cgb dgebacf gc +fgaebd cg bdaec gdafb agbcfd gdcbef bgcad gfac gcb cdgabef | cg cg fdcagb cbg +fbegcd cbd adcefb dageb afcb bc aefdc ecdab fgdeca fcdbega | efabcd cedba gadfec cb +aecbfdg fbg gf bafeg dbefa fcge gcbea fcaegb dgceab fcbdga | gecf egdcabf bgf bfgea +fgeab ca afcebg bdacfeg cfaedg gcfdb baec bfadeg bafgc acf | gebdcfa ecba ca fadegcb +dbcfg fgd bdegcaf fgec aegbdf ecdfab fbedc dacgb gdcebf gf | cefg dcbef fcge gbcadfe +bdfegc cbegaf gecbf dfcage bdacg ed bedf ced adcbefg gebcd | ed bcgafe cdgba cbgef +egadfb cdbfeg cegd fecab cgb gbdefca cg fgcdab egfdb bfceg | gbdfcae bgc cg cgb +gcafb gcf dcaebfg ecagb gf abcdeg gaef cafbge fdbac fegbdc | fgae cfgab fg bagce diff --git a/2021/08/sample0 b/2021/08/sample0 new file mode 100644 index 0000000..42b3bfd --- /dev/null +++ b/2021/08/sample0 @@ -0,0 +1 @@ +acedgfb cdfbe gcdfa fbcad dab cefabd cdfgeb eafb cagedb ab | cdfeb fcadb cdfeb cdbaf diff --git a/2021/08/test.mjs b/2021/08/test.mjs new file mode 100644 index 0000000..9c5fc8b --- /dev/null +++ b/2021/08/test.mjs @@ -0,0 +1,34 @@ +// https://adventofcode.com/2021/day/08 + +import tap from "tap"; +import fs from "fs-extra"; + +import * as p1 from "./part1.mjs"; +import * as p2 from "./part2.mjs"; + +const sample0 = fs.readFile("sample0", "utf8").then(p1.processInput); +const sample = fs.readFile("sample", "utf8").then(p1.processInput); +const input = fs.readFile("input", "utf8").then(p1.processInput); + +tap.test("part1", async (t) => { + t.equal(p1.solution(await sample), 26); + t.equal(p1.solution(await input), 375); +}); + +tap.test("part2", async (t) => { + const [ s0 ] = await sample0; + t.match( + p2.findMapping([...s0.input,...s0.output]), { + d: 'a', + e: 'b', + a: 'c', + f: 'd', + g: 'e', + b: 'f', + c: 'g', + } + ); + t.match(p2.decodedOutput(s0),5353); + t.equal(p2.solution(await sample), 61229); + t.equal(p2.solution(await input), 1019355); +}); diff --git a/friends/eric b/friends/eric index a85f406..f9f3e07 160000 --- a/friends/eric +++ b/friends/eric @@ -1 +1 @@ -Subproject commit a85f4063d48dd84dc366081533e2c17ee479d3d5 +Subproject commit f9f3e070d56e500e5dae053110de58ddfe332972 diff --git a/friends/waltman/2021 b/friends/waltman/2021 index 3c925eb..441da0a 160000 --- a/friends/waltman/2021 +++ b/friends/waltman/2021 @@ -1 +1 @@ -Subproject commit 3c925ebeb9f531a1f0040dc2a48fcbb7ffbb9281 +Subproject commit 441da0a9c244cef1df7efdc34f1e85ff9a11d14e