Files
aocutil/2021/16.js
nim-ka 0485b4f035 .
2022-11-19 22:52:51 +00:00

145 lines
3.7 KiB
JavaScript

function toInt(bits) {
return parseInt(bits.join(""), 2)
}
class Packet {
full = []
version = []
type = []
groups = [[]]
lengthType = []
length = []
children = []
done = false
constructor(bits = []) {
for (let bit of bits) {
this.pushBit(bit)
}
}
pushBit(bit) {
if (this.version.length < 3) {
this.version.push(bit)
return this.full.push(bit)
}
if (this.type.length < 3) {
this.type.push(bit)
return this.full.push(bit)
}
if (this.isLiteral()) {
if (this.groups.last.length < 5) {
this.groups.last.push(bit)
return this.full.push(bit)
}
if (this.groups.last[0]) {
this.groups.push([bit])
return this.full.push(bit)
}
} else {
if (this.children.length == 0) {
this.children.push(new Packet())
}
if (this.lengthType.length < 1) {
this.lengthType.push(bit)
return this.full.push(bit)
}
if (!this.lengthType[0]) {
if (this.length.length < 15) {
this.length.push(bit)
return this.full.push(bit)
}
if (this.children.map((e) => e.full.length).sum() < toInt(this.length)) {
this.children.last.pushBit(bit)
if (this.children.last.done) {
this.children.push(new Packet([bit]))
}
return this.full.push(bit)
}
} else {
if (this.length.length < 11) {
this.length.push(bit)
return this.full.push(bit)
}
if (!this.children.last.done) {
this.children.last.pushBit(bit)
if (this.children.last.done) {
if (this.children.length < toInt(this.length)) {
this.children.push(new Packet([bit]))
return this.full.push(bit)
}
} else {
return this.full.push(bit)
}
}
}
}
this.done = true
}
isLiteral() {
return toInt(this.type) == 4
}
getLiteralValue() {
return toInt(this.groups.flatMap((e) => e.slice(1)))
}
getVersionSum() {
return toInt(this.version) + this.children.map((e) => e.getVersionSum()).sum()
}
getValue() {
if (this.isLiteral()) {
return this.getLiteralValue()
} else {
let operands = this.children.map((e) => e.getValue())
switch (toInt(this.type)) {
case 0:
return operands.sum()
case 1:
return operands.prod()
case 2:
return operands.min()
case 3:
return operands.max()
case 5:
return +(operands[0] > operands[1])
case 6:
return +(operands[0] < operands[1])
case 7:
return +(operands[0] == operands[1])
}
}
}
}
function day16(input, part2) {
let bits = input.split("").flatMap((e) => parseInt(e, 16).toString(2).padStart(4, "0").split("").num())
return new Packet(bits)[part2 ? "getValue" : "getVersionSum"]()
}
if (typeof window == "undefined") {
module.exports = day16
}