Public
Edited
Dec 16, 2021
1 star
Insert cell
Insert cell
Insert cell
function toBinArray(input) {
return input
.split("")
.map((h) => AOC.decToBinary(parseInt(h, 16), 4).split(""))
.flat()
.map(Number);
}
Insert cell
function toDec(bits) {
return parseInt(bits.join(""), 2);
}
Insert cell
Insert cell
function toPacket(bin) {
let [bits, todo] = AOC.splitAt(3, bin);
const version = toDec(bits);

[bits, todo] = AOC.splitAt(3, todo);
const id = toDec(bits);

let val = 0;
const subPackets = [];
if (id == 4) {
// Literal
val = [];
[bits, todo] = AOC.splitAt(5, todo);
while (bits[0] === 1) {
val.push(bits.slice(1));
[bits, todo] = AOC.splitAt(5, todo);
}
val.push(bits.slice(1));
val = toDec(val.flat());
} else {
// Operator
[bits, todo] = AOC.splitAt(1, todo);

if (bits[0] === 0) {
// Bit length of sub-packets to follow
[bits, todo] = AOC.splitAt(15, todo);
const bLen = toDec(bits);
let subTodo = todo.slice(0, bLen);
while (subTodo.length > 0) {
const [sp, td] = toPacket(subTodo);
subPackets.push(sp);
subTodo = td;
}
todo = todo.slice(bLen);
} else {
// Number of sub-packets to follow
[bits, todo] = AOC.splitAt(11, todo);
const nPackets = toDec(bits);
for (let i = 0; i < nPackets; i++) {
const [sp, td] = toPacket(todo);
subPackets.push(sp);
todo = td;
}
}
}

const packet = {
version: version,
id: id,
val: val,
subPackets: subPackets
};
return [packet, todo];
}
Insert cell
function parse(input) {
const bin = toBinArray(input);
return toPacket(bin)[0];
}
Insert cell
Insert cell
function versionCount(packet) {
return packet.version + AOC.sum(packet.subPackets.map(versionCount));
}
Insert cell
function part1(input) {
return versionCount(parse(input));
}
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
function evaluate(p) {
switch (p.id) {
case 0:
return AOC.sum(p.subPackets.map(evaluate));
case 1:
return AOC.product(p.subPackets.map(evaluate));
case 2:
return Math.min(...p.subPackets.map(evaluate));
case 3:
return Math.max(...p.subPackets.map(evaluate));
case 4:
return p.val + AOC.sum(p.subPackets.map(evaluate));
case 5:
return evaluate(p.subPackets[0]) > evaluate(p.subPackets[1]) ? 1 : 0;
case 6:
return evaluate(p.subPackets[0]) < evaluate(p.subPackets[1]) ? 1 : 0;
case 7:
return evaluate(p.subPackets[0]) === evaluate(p.subPackets[1]) ? 1 : 0;
}
return 0;
}
Insert cell
function part2(input) {
return evaluate(parse(input));
}
Insert cell
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