From 0da07275d02d53f29341235c24225d619964de7e Mon Sep 17 00:00:00 2001 From: Yanick Champoux Date: Wed, 8 Dec 2021 12:45:55 -0500 Subject: [PATCH 1/5] first draft --- 2021/08/part1.mjs | 34 +++++++++++++ 2021/08/part2.mjs | 122 ++++++++++++++++++++++++++++++++++++++++++++++ 2021/08/sample | 10 ++++ 2021/08/sample0 | 1 + 2021/08/test.mjs | 34 +++++++++++++ 5 files changed, 201 insertions(+) create mode 100644 2021/08/part1.mjs create mode 100644 2021/08/part2.mjs create mode 100644 2021/08/sample create mode 100644 2021/08/sample0 create mode 100644 2021/08/test.mjs 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..728d567 --- /dev/null +++ b/2021/08/part2.mjs @@ -0,0 +1,122 @@ +import fs from "fs-extra"; +import fp from "lodash/fp.js"; +import _ from "lodash"; + +import * as p1 from './part1.mjs'; + +function decodedDigits(mapping) { + const s = fp.invert(mapping); + let solution = fp.invert(p1.digits); + solution = fp.mapKeys( + k => k.split('').map( + l => s[l] + ).join('') + ,solution ); + + solution = fp.mapKeys( k => { k = k.split('').sort().join(''); return k }, solution ); + + return solution; +} + +function guess(unknowns,guessed={},inputs) { + console.log({unknowns,guessed}); + + const [ next ] = Object.keys(unknowns); + + if(!next) return guessed; + + + if(unknowns[next].size === 0) return; + + + for ( const p of unknowns[next].values() ) { + let newUnknowns = fp.omit(next, unknowns); + newUnknowns = fp.mapValues( + s => { + const x = new Set(s.values()); + x.delete(p); + return x; + }, newUnknowns ); + + //console.log({ newUnknowns }) + if( + Object.values(newUnknowns).some( s => s.size === 0 ) + ) continue; + + const r = guess( newUnknowns, { ...guessed, [next]: p }, inputs ); + if(r) { + const s = fp.invert(r); + let solution = fp.invert(p1.digits); + solution = fp.mapKeys( + k => k.split('').map( + l => s[l] + ).join('') + ,solution ); + + solution = fp.mapKeys( k => { k = k.split('').sort().join(''); return k }, solution ); + + console.log({r, solution }); + console.log({inputs}) + + if( inputs.some( i => ! solution.hasOwnProperty(i.join('')) ) ) { + console.log("Oh noes"); + } else { + console.log("Oh yea"); + return r; + } + + } + } +} + +export function findMapping(input) { + const values = 'abcdefg'.split(''); + + const possibility = Object.fromEntries(values.map( + v => [ v, new Set(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] = new Set( + p.filter( x => possibility[l].has(x) ) + ); + } + // console.log(possibility); + } + + + + const one = input.find( i => i.length === 2 ); + const seven = input.find( i => i.length === 3 ); + const [a] = seven.filter( x => !one.includes(x) ); + + for( const l of Object.values(possibility) ) { + l.delete('a'); + } + + possibility[a] = new Set(['a']); + console.log(possibility); + + return guess(possibility,{},input); +} + +export function decodedOutput({input,output}) { + const mapping = findMapping([...input,...output]); + + const digits = decodedDigits(mapping); + + console.log({ digits, output }); + + 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..30cc8f7 --- /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), 26); +}); + +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); +}); From fe5a92fb37641c05600cb4033c2af805543e9948 Mon Sep 17 00:00:00 2001 From: Yanick Champoux Date: Wed, 8 Dec 2021 12:50:53 -0500 Subject: [PATCH 2/5] refactor --- 2021/08/part2.mjs | 131 +++++++++++++++++++--------------------------- 2021/08/test.mjs | 2 +- 2 files changed, 54 insertions(+), 79 deletions(-) diff --git a/2021/08/part2.mjs b/2021/08/part2.mjs index 728d567..97cac62 100644 --- a/2021/08/part2.mjs +++ b/2021/08/part2.mjs @@ -2,121 +2,96 @@ import fs from "fs-extra"; import fp from "lodash/fp.js"; import _ from "lodash"; -import * as p1 from './part1.mjs'; +import * as p1 from "./part1.mjs"; function decodedDigits(mapping) { - const s = fp.invert(mapping); - let solution = fp.invert(p1.digits); - solution = fp.mapKeys( - k => k.split('').map( - l => s[l] - ).join('') - ,solution ); + const s = fp.invert(mapping); + let solution = fp.invert(p1.digits); + solution = fp.mapKeys( + (k) => + k + .split("") + .map((l) => s[l]) + .join(""), + solution + ); - solution = fp.mapKeys( k => { k = k.split('').sort().join(''); return k }, solution ); + solution = fp.mapKeys((k) => { + k = k.split("").sort().join(""); + return k; + }, solution); - return solution; + return solution; } -function guess(unknowns,guessed={},inputs) { - console.log({unknowns,guessed}); +function guess(unknowns, guessed = {}, inputs) { + const [next] = Object.keys(unknowns); - const [ next ] = Object.keys(unknowns); + if (!next) return guessed; - if(!next) return guessed; + if (unknowns[next].size === 0) return; - - if(unknowns[next].size === 0) return; - - - for ( const p of unknowns[next].values() ) { + for (const p of unknowns[next].values()) { let newUnknowns = fp.omit(next, unknowns); - newUnknowns = fp.mapValues( - s => { - const x = new Set(s.values()); - x.delete(p); - return x; - }, newUnknowns ); + newUnknowns = fp.mapValues((s) => { + const x = new Set(s.values()); + x.delete(p); + return x; + }, newUnknowns); - //console.log({ newUnknowns }) - if( - Object.values(newUnknowns).some( s => s.size === 0 ) - ) continue; + if (Object.values(newUnknowns).some((s) => s.size === 0)) continue; - const r = guess( newUnknowns, { ...guessed, [next]: p }, inputs ); - if(r) { - const s = fp.invert(r); - let solution = fp.invert(p1.digits); - solution = fp.mapKeys( - k => k.split('').map( - l => s[l] - ).join('') - ,solution ); + const r = guess(newUnknowns, { ...guessed, [next]: p }, inputs); - solution = fp.mapKeys( k => { k = k.split('').sort().join(''); return k }, solution ); + if (r) { + const solution = decodedDigits(r); - console.log({r, solution }); - console.log({inputs}) - - if( inputs.some( i => ! solution.hasOwnProperty(i.join('')) ) ) { - console.log("Oh noes"); - } else { - console.log("Oh yea"); + if (inputs.every((i) => solution.hasOwnProperty(i.join("")))) { return r; } - } } } export function findMapping(input) { - const values = 'abcdefg'.split(''); + const values = "abcdefg".split(""); - const possibility = Object.fromEntries(values.map( - v => [ v, new Set(values) ] - )); + const possibility = Object.fromEntries( + values.map((v) => [v, new Set(values)]) + ); - for ( const seq of input ) { - const p = Object.values(p1.digits).filter( - d => d.length === seq.length - ).join('').split(''); + 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] = new Set( - p.filter( x => possibility[l].has(x) ) - ); + for (const l of seq) { + possibility[l] = new Set(p.filter((x) => possibility[l].has(x))); } - // console.log(possibility); } + const one = input.find((i) => i.length === 2); + const seven = input.find((i) => i.length === 3); + const [a] = seven.filter((x) => !one.includes(x)); - - const one = input.find( i => i.length === 2 ); - const seven = input.find( i => i.length === 3 ); - const [a] = seven.filter( x => !one.includes(x) ); - - for( const l of Object.values(possibility) ) { - l.delete('a'); + for (const l of Object.values(possibility)) { + l.delete("a"); } - possibility[a] = new Set(['a']); - console.log(possibility); + possibility[a] = new Set(["a"]); - return guess(possibility,{},input); + return guess(possibility, {}, input); } -export function decodedOutput({input,output}) { - const mapping = findMapping([...input,...output]); +export function decodedOutput({ input, output }) { + const mapping = findMapping([...input, ...output]); const digits = decodedDigits(mapping); - console.log({ digits, output }); - - return parseInt(output.map( e => digits[e.join('')] ).join('')); + return parseInt(output.map((e) => digits[e.join("")]).join("")); } export function solution(input) { - - return _.sum( input.map( decodedOutput ) ); - + return _.sum(input.map(decodedOutput)); } diff --git a/2021/08/test.mjs b/2021/08/test.mjs index 30cc8f7..9c5fc8b 100644 --- a/2021/08/test.mjs +++ b/2021/08/test.mjs @@ -12,7 +12,7 @@ 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), 26); + t.equal(p1.solution(await input), 375); }); tap.test("part2", async (t) => { From e01357f8afa0c1da41fbf2eefed486d34fdf5a7a Mon Sep 17 00:00:00 2001 From: Yanick Champoux Date: Wed, 8 Dec 2021 13:21:28 -0500 Subject: [PATCH 3/5] refactor --- 2021/08/part2.mjs | 27 +++++++++++---------------- 1 file changed, 11 insertions(+), 16 deletions(-) diff --git a/2021/08/part2.mjs b/2021/08/part2.mjs index 97cac62..cc041e3 100644 --- a/2021/08/part2.mjs +++ b/2021/08/part2.mjs @@ -34,30 +34,27 @@ function guess(unknowns, guessed = {}, inputs) { for (const p of unknowns[next].values()) { let newUnknowns = fp.omit(next, unknowns); newUnknowns = fp.mapValues((s) => { - const x = new Set(s.values()); - x.delete(p); - return x; + return s.filter( x => x !== p ) }, newUnknowns); if (Object.values(newUnknowns).some((s) => s.size === 0)) continue; const r = guess(newUnknowns, { ...guessed, [next]: p }, inputs); - if (r) { - const solution = decodedDigits(r); + if (!r) continue; - if (inputs.every((i) => solution.hasOwnProperty(i.join("")))) { - return r; - } - } + const solution = decodedDigits(r); + + if (inputs.every((i) => solution.hasOwnProperty(i.join("")))) + return r; } } export function findMapping(input) { const values = "abcdefg".split(""); - const possibility = Object.fromEntries( - values.map((v) => [v, new Set(values)]) + let possibility = Object.fromEntries( + values.map((v) => [v, [ ...values ]]) ); for (const seq of input) { @@ -67,7 +64,7 @@ export function findMapping(input) { .split(""); for (const l of seq) { - possibility[l] = new Set(p.filter((x) => possibility[l].has(x))); + possibility[l] = _.intersection( possibility[l], p); } } @@ -75,11 +72,9 @@ export function findMapping(input) { const seven = input.find((i) => i.length === 3); const [a] = seven.filter((x) => !one.includes(x)); - for (const l of Object.values(possibility)) { - l.delete("a"); - } + possibility = fp.mapValues( fp.reject('a'), possibility); - possibility[a] = new Set(["a"]); + possibility[a] = ["a"]; return guess(possibility, {}, input); } From 8a8d79f4362acd31b6e619941dc4ad4fd0367607 Mon Sep 17 00:00:00 2001 From: Yanick Champoux Date: Wed, 8 Dec 2021 13:35:19 -0500 Subject: [PATCH 4/5] refactor --- 2021/08/part2.mjs | 43 +++++++++++++++++-------------------------- 1 file changed, 17 insertions(+), 26 deletions(-) diff --git a/2021/08/part2.mjs b/2021/08/part2.mjs index cc041e3..44b32ab 100644 --- a/2021/08/part2.mjs +++ b/2021/08/part2.mjs @@ -1,4 +1,3 @@ -import fs from "fs-extra"; import fp from "lodash/fp.js"; import _ from "lodash"; @@ -6,22 +5,17 @@ import * as p1 from "./part1.mjs"; function decodedDigits(mapping) { const s = fp.invert(mapping); - let solution = fp.invert(p1.digits); - solution = fp.mapKeys( - (k) => + + return _.flow([ + fp.invert, + fp.mapKeys((k) => k .split("") .map((l) => s[l]) - .join(""), - solution - ); - - solution = fp.mapKeys((k) => { - k = k.split("").sort().join(""); - return k; - }, solution); - - return solution; + .join("") + ), + fp.mapKeys((k) => k.split("").sort().join("")), + ])(p1.digits); } function guess(unknowns, guessed = {}, inputs) { @@ -29,13 +23,11 @@ function guess(unknowns, guessed = {}, inputs) { if (!next) return guessed; - if (unknowns[next].size === 0) return; - - for (const p of unknowns[next].values()) { - let newUnknowns = fp.omit(next, unknowns); - newUnknowns = fp.mapValues((s) => { - return s.filter( x => x !== p ) - }, newUnknowns); + 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; @@ -53,9 +45,7 @@ function guess(unknowns, guessed = {}, inputs) { export function findMapping(input) { const values = "abcdefg".split(""); - let possibility = Object.fromEntries( - values.map((v) => [v, [ ...values ]]) - ); + let possibility = Object.fromEntries(values.map((v) => [v, values])); for (const seq of input) { const p = Object.values(p1.digits) @@ -64,15 +54,16 @@ export function findMapping(input) { .split(""); for (const l of seq) { - possibility[l] = _.intersection( possibility[l], p); + 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 = fp.mapValues(fp.reject("a"), possibility); possibility[a] = ["a"]; From d7c24ca989a347de8b5bc17ea3a1f6b986fde111 Mon Sep 17 00:00:00 2001 From: Yanick Champoux Date: Wed, 8 Dec 2021 13:36:27 -0500 Subject: [PATCH 5/5] update friends --- friends/eric | 2 +- friends/waltman/2021 | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) 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