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) {
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 {
[bits, todo] = AOC.splitAt(1, todo);
if (bits[0] === 0) {
[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 {
[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];
}