Published
Edited
Dec 20, 2020
Insert cell
Insert cell
Insert cell
input_text = (await FileAttachment(
"Avent of Code 2020 - Day 19.txt"
).text()).trim()
Insert cell
function parseInput(input) {
let [rulesArr, messages] = input.split('\n\n').map(txt => txt.split('\n'));
const rulesArr2 = [];
for (let rule of rulesArr) {
let [nr, match] = rule.split(': ');
nr |= 0;
match = match
.split(' | ')
.map(rulePart =>
rulePart
.split(' ')
.map(nr => (+nr + "" === nr ? +nr : nr.slice(1, nr.length - 1)))
);

const isString = typeof match[0][0] === "string";

const pair = [
nr,
{
isString,
match: isString ? match[0] : match
}
];
rulesArr2.push(pair);
}

// sort by rule nr
rulesArr2.sort((a, b) => a[0] - b[0]);

const rules = new Map();
const stringRules = new Map(); // rules that don't refer to other rules
for (const [nr, rule] of rulesArr2) {
rules.set(nr, rule);
if (rule.isString) stringRules.set(nr, rule);
}

return { rules, stringRules, messages };
}
Insert cell
Insert cell
input = parseInput(input_text)
Insert cell
Insert cell
flattenRules(testInput)
Insert cell
/*
If you uncomment the next cells, it turns out there are 2097152 possible strings that match rule 0
Intersect that with the messages in the input and you get 220 matches.

Output looks like this:

answer1 = Object {
flatRules: Object {passes: 10, flattened: Map(138)}
matchesRule0: Array(220) ["aaabbaabbaaababaaaaabbbb", "babaaaabaabbbababbbabaaa", "abbaabaabaaabababaaababb", "bbbabbaabbaababbabaaabaa", "bbaabaababbbaababbbbaaab", "baaaababaababbbbabbbabab", "bbaabbbaaaaabaabbabababb", "abababbaabbaabaaababbbbb", "abbbabbaabbbaabaaaabaaab", "ababbbaaaababaabbaaaabbb", "abbbbaabaaaababbbbbbaaaa", "bbbababababaabababaaaaab", "aabababaabbababbaabbbaaa", "abbaababbabbbbabbbbabbab", "baaabbababbbbbabaabbbabb", "aabaabbbbaabaababaababaa", "bbaabaaabbbbbbaaabababaa", "bbaabbabaaaaababbbbbabab", "abbabbababaabbabbaaabbba", "babaaabbabbaaaabbaabaabb", …]
time: 2486
}

(commented out because sloooow)
*/
Insert cell
// answer1 = {
// const t0 = performance.now();
// const flatRules = flattenRules(input);
// const rule0 = new Set(flatRules.flattened.get(0).match);
// let matchesRule0 = [];
// for (const msg of input.messages) {
// if (rule0.has(msg)) matchesRule0.push(msg);
// }
// return { flatRules, matchesRule0, time: performance.now() - t0 };
// }
Insert cell
Insert cell
Insert cell

One platform to build and deploy the best data apps

Experiment and prototype by building visualizations in live JavaScript notebooks. Collaborate with your team and decide which concepts to build out.
Use Observable Framework to build data apps locally. Use data loaders to build in any language or library, including Python, SQL, and R.
Seamlessly deploy to Observable. Test before you ship, use automatic deploy-on-commit, and ensure your projects are always up-to-date.
Learn more