Public
Edited
Dec 11, 2021
1 star
Insert cell
Insert cell
Insert cell
function parse(input) {
const toObj = (line) => {
const blocks = line.split(" | ").map((l) => l.split(" "));
return { in: blocks[0], out: blocks[1] };
};
return input.split("\n").map(toObj);
}
Insert cell
Insert cell
Insert cell
function part1(input) {
return parse(input)
.map((blocks) =>
blocks.out
.map((b) => b.length)
.filter((len) => len == 2 || len == 3 || len == 4 || len == 7)
)
.flat().length;
}
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
function alpha(s) {
return s.split("").sort().join("");
}
Insert cell
Insert cell
function blockPossibilities(block) {
switch (block.length) {
case 2:
return [1];
case 3:
return [7];
case 4:
return [4];
case 7:
return [8];
case 5:
return [2, 3, 5];
case 6:
return [0, 6, 9];
}
throw "Unexpected length of " + block + ": " + block.length;
}
Insert cell
Insert cell
digitPairs = [
[6, 2, 4, 4, 3, 4, 5, 3, 6, 5], // 0 and 0,1,2...
[2, 2, 1, 2, 2, 1, 1, 2, 2, 2], // 1 and 0,1,2...
[4, 1, 5, 4, 2, 3, 4, 2, 5, 4], // 2 and 0,1,2...
[4, 2, 4, 5, 3, 4, 4, 3, 5, 5], // 3 and 0,1,2...
[3, 2, 2, 3, 4, 3, 3, 2, 4, 4], // 4 and 0,1,2...
[4, 1, 3, 4, 3, 5, 5, 2, 5, 5], // 5 and 0,1,2...
[5, 1, 4, 4, 3, 5, 6, 2, 6, 5], // 6 and 0,1,2...
[3, 2, 2, 3, 2, 2, 2, 3, 3, 3], // 7 and 0,1,2...
[6, 2, 5, 5, 4, 5, 6, 3, 7, 6], // 8 and 0,1,2...
[5, 2, 4, 5, 4, 5, 5, 3, 6, 6] // 9 and 0,1,2...
]
Insert cell
Insert cell
Insert cell
function entryValues(blocks) {
return blocks.map((block) => [alpha(block), blockPossibilities(block)]);
}
Insert cell
function singletons(blocks) {
return new Map(
entryValues(blocks)
.filter(([_, ds]) => ds.length == 1)
.map(([block, ds]) => [block, ds[0]])
);
}
Insert cell
Insert cell
function processEntry(entry) {
const confirmed = singletons(entry.in);
const bs = entryValues(entry.in).filter(([_, ds]) => ds.length > 1);

for (const [signal, candidates] of bs) {
let digit;
const wires = new Set(signal.split(""));

for (const candidateDigit of candidates) {
let isValid = true;
confirmed.forEach((d, cBlock) => {
const obs = AOC.intersection(wires, new Set(cBlock.split(""))).size;
if (obs != digitPairs[d][candidateDigit]) {
isValid = false;
}
});
if (isValid) {
digit = candidateDigit;
}
}
confirmed.set(signal, digit);
}
return Number(entry.out.map((b) => confirmed.get(alpha(b))).join(""));
}
Insert cell
function part2(input) {
return AOC.sum(parse(input).map(processEntry));
}
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more