Published
Edited
Dec 10, 2021
2 stars
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
source = ({
test: {value: {corrupt: 26397, incomplete: 288957}, text: testPuzzleInput},
real: {value: {corrupt: 442131, incomplete: 3646451424}, text: realPuzzleInput},
})[kind]
Insert cell
Insert cell
expected = (c) => ({ // matching openng and closing pairs
"(": ")",
"[": "]",
"{": "}",
"<": ">"
})[c]
Insert cell
data = source.text.split("\n")
Insert cell
analysed = analyse(data)
Insert cell
analyse = (data) => data.map(lexer)
Insert cell
lexer = (text, line) => {

const open = "({<[";
const close = ")}>]";

const expectations = [];
let corrupted = null;
[...text].forEach(
(actual, column) => {
if (open.includes(actual))
expectations.push(expected(actual)); // keep a stack of opening characters
if (close.includes(actual)) { // got a closing one…
const expected = expectations.pop();
if (expected !== actual) { // does it match up with its peer?
corrupted = ({line, column, expected, actual, status: "corrupt"});
}
}
}
)
return corrupted || ({expectations, status: "incomplete"});
}
Insert cell
Insert cell
scorers = statuses.reduce( // generate object with proper data and scorer
(accu, status) =>
({
...accu,
[status]: {
data: filter(analysed, status),
scorer: scorer[status],
}
}),
{}
)
Insert cell
scorer = ({
corrupt: (list) =>
_.sum(list.map(pointers["corrupt"])),

incomplete: (list) =>
middle( // take the middle score
list
.map(pointers["incomplete"]) // score each line
.map(score) // convert to score
.sort((a, b) => a > b) // make sure its sorted to pick the right middle one
)
})
Insert cell
score = (list) => list.reduce((accu, k) => 5 * accu + k, 0)
Insert cell
pointers = ({ // generate object containing point counters for each type

corrupt: (c) => // take a character, return its corruptness points
punten["corrupt"](c?.actual),

incomplete: (list) => // take a list of completeness string, return its points
list
.expectations
.reverse()
.map(punten["incomplete"]),

})
Insert cell
punten = ({ // take a character, return its points
corrupt: (c) =>
({
")": 3,
"]": 57,
"}": 1197,
">": 25137,
})[c],
incomplete: (c) =>
({
")": 1,
"]": 2,
"}": 3,
">": 4,
})[c],

})
Insert cell
middle = (list) => list[(list.length / 2)|0]
Insert cell
filter = (list, s) => list.filter(({status}) => status === s)
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