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

149 lines
4.2 KiB
JavaScript

class SnailfishNumber {
static fromArr(arr, parent = null, isRight) {
let num = new SnailfishNumber()
return num.initialize(
arr[0] instanceof Array ? SnailfishNumber.fromArr(arr[0], num, false) : arr[0],
arr[1] instanceof Array ? SnailfishNumber.fromArr(arr[1], num, true) : arr[1],
parent, isRight)
}
initialize(left, right, parent, isRight) {
this.left = left
this.right = right
this.parent = parent
this.isRight = isRight
return this
}
explode(depth = 0) {
if (this.left instanceof SnailfishNumber) {
if (this.left.explode(depth + 1)) {
return true
}
}
if (this.right instanceof SnailfishNumber) {
if (this.right.explode(depth + 1)) {
return true
}
}
if (!(this.left instanceof SnailfishNumber) && !(this.right instanceof SnailfishNumber) && depth >= 4) {
let lastNode = this
let node = this.parent
while (node && node.left == lastNode) {
lastNode = node
node = node.parent
}
if (node) {
if (!(node.left instanceof SnailfishNumber)) {
node.left += this.left
} else {
node = node.left
while (node.right instanceof SnailfishNumber) {
node = node.right
}
node.right += this.left
}
}
lastNode = this
node = this.parent
while (node && node.right == lastNode) {
lastNode = node
node = node.parent
}
if (node) {
if (!(node.right instanceof SnailfishNumber)) {
node.right += this.right
} else {
node = node.right
while (node.left instanceof SnailfishNumber) {
node = node.left
}
node.left += this.right
}
}
if (!this.isRight) {
this.parent.left = 0
} else {
this.parent.right = 0
}
return true
}
return false
}
split() {
if (this.left instanceof SnailfishNumber) {
if (this.left.split()) {
return true
}
} else if (this.left >= 10) {
this.left = SnailfishNumber.fromArr([Math.floor(this.left / 2), Math.ceil(this.left / 2)], this, false)
return true
}
if (this.right instanceof SnailfishNumber) {
if (this.right.split()) {
return true
}
} else if (this.right >= 10) {
this.right = SnailfishNumber.fromArr([Math.floor(this.right / 2), Math.ceil(this.right / 2)], this, true)
return true
}
return false
}
reduce() {
while (this.explode() || this.split());
return this
}
add(that) {
let parent = SnailfishNumber.fromArr([this, that])
this.parent = parent
this.isRight = false
that.parent = parent
that.isRight = true
return parent.reduce()
}
magnitude() {
return 3 * (this.left instanceof SnailfishNumber ? this.left.magnitude() : this.left) +
2 * (this.right instanceof SnailfishNumber ? this.right.magnitude() : this.right)
}
toString() {
return "[" + this.left.toString() + "," + this.right.toString() + "]"
}
}
function day18(input, part2) {
let lines = input.split("\n")
if (!part2) {
let nums = lines.map((line) => SnailfishNumber.fromArr(JSON.parse(line)))
return nums.reduce((a, b) => a.add(b)).magnitude()
} else {
let pairs = lines.flatMap((e) => lines.filter((f) => e != f).map((f) => [e, f].map((e) => SnailfishNumber.fromArr(JSON.parse(e)))))
return pairs.map((e) => e[0].add(e[1]).magnitude()).max()
}
}
if (typeof window == "undefined") {
module.exports = day18
}