UNPKG

@alexaegis/advent-of-code-lib

Version:
359 lines (358 loc) 8.37 kB
import { y as nonNullish, ao as Direction, az as Vec2 } from "./array.polyfill-r5d1OMxR.js"; import "@alexaegis/common"; import "js-sdsl"; import "./index-41yGvuWH.js"; import "./map.js"; import "node:perf_hooks"; import "node:fs/promises"; import "node:path"; import "node:fs"; import "kolorist"; import "./set.js"; class BPlusTree { } class BinaryTree { parent; parentSide; _left; value; _right; constructor(value) { this.value = value; } set left(left) { if (this._left) { this._left.parent = void 0; this._left.parentSide = void 0; } this._left = left; if (this._left) { this._left.parent = this; this._left.parentSide = "left"; } } get left() { return this._left; } set right(right) { if (this._right) { this._right.parent = void 0; this._right.parentSide = void 0; } this._right = right; if (this._right) { this._right.parent = this; this._right.parentSide = "right"; } } get right() { return this.right; } getSide(side) { return side === "left" ? this.left : this.right; } setSide(side, value) { if (side === "left") { this.left = value; } else { this.right = value; } } get root() { let parent = this.parent ?? this; while (parent.parent) { parent = parent.parent; } return parent; } get depth() { return 1 + (this.parent?.depth ?? 0); } *leftToRight() { if (this.left) { yield* this.left.leftToRight(); } yield this.value; if (this.right) { yield* this.right.leftToRight(); } } *rightToLeft() { if (this.right) { yield* this.right.rightToLeft(); } yield this.value; if (this.left) { yield* this.left.rightToLeft(); } } toString() { return `[${this.left?.toString()},${String(this.value)},${this.right?.toString()}]`; } print() { console.log(this.toString()); } } const isNestedPair = (nestedPair) => { return typeof nestedPair === "object"; }; class PairTree { parent; parentSide; leftTree; leftValue; rightTree; rightValue; constructor(left, right) { if (left instanceof PairTree) { this.leftTree = left; this.leftTree.parent = this; this.leftTree.parentSide = "left"; } else { this.leftValue = left; } if (right instanceof PairTree) { this.rightTree = right; this.rightTree.parent = this; this.rightTree.parentSide = "right"; } else { this.rightValue = right; } } set left(left) { this.detachSubTree("left"); if (left instanceof PairTree) { this.leftTree = left; this.leftTree.parent = this; this.leftTree.parentSide = "left"; this.leftValue = void 0; } else { this.leftValue = left; } } get left() { return this.leftTree ?? this.leftValue; } set right(right) { this.detachSubTree("right"); if (right instanceof PairTree) { this.rightTree = right; this.rightTree.parent = this; this.rightTree.parentSide = "right"; this.rightValue = void 0; } else { this.rightValue = right; } } get right() { return this.rightTree ?? this.rightValue; } detachSubTree(side) { if (side === "right" && this.rightTree) { this.rightTree.parent = void 0; this.rightTree.parentSide = void 0; this.rightTree = void 0; } else if (side === "left" && this.leftTree) { this.leftTree.parent = void 0; this.leftTree.parentSide = void 0; this.leftTree = void 0; } } join(other) { const parent = this.parent; const parentSide = this.parentSide; const newNode = new PairTree(this, other); if (parent && parentSide) { parent.setSide(parentSide, newNode); } return newNode; } getSide(side) { return side === "left" ? this.left : this.right; } setSide(side, value) { if (side === "left") { this.left = value; } else { this.right = value; } } findNode(value, side) { for (const node of this.root.leftToRightNodes()) { if (side !== "right" && node.leftValue === value) { return node; } else if (side !== "left" && node.rightValue === value) { return node; } } return void 0; } inOrderSuccessor() { const iterator = this.root.leftToRightNodes(); for (let i = iterator.next(); !i.done; i = iterator.next()) { if (i.value === this) { return iterator.next().value; } } return void 0; } inOrderPredecessor() { const iterator = this.root.rightToLeftNodes(); for (let i = iterator.next(); !i.done; i = iterator.next()) { if (i.value === this) { return iterator.next().value; } } return void 0; } leftMostTree() { let next = this; while (next.leftTree) { next = next.leftTree; } return next; } rightMostTree() { let next = this; while (next.rightTree) { next = next.rightTree; } return next; } replace(next) { if (this.parent) { if (this.parentSide === "right") { this.parent.right = next; } else { this.parent.left = next; } } } get root() { let parent = this.parent ?? this; while (parent.parent) { parent = parent.parent; } return parent; } get depth() { return 1 + (this.parent?.depth ?? 0); } static fromNestedPairs(nestedPairs) { let left; let right; if (isNestedPair(nestedPairs)) { left = isNestedPair(nestedPairs[0]) ? PairTree.fromNestedPairs(nestedPairs[0]) : nestedPairs[0]; right = isNestedPair(nestedPairs[1]) ? PairTree.fromNestedPairs(nestedPairs[1]) : nestedPairs[1]; } else { throw new Error("not a full binary tree source"); } return new PairTree(left, right); } *leftToRightNodes(skipEmpty = true) { if (this.leftTree) { yield* this.leftTree.leftToRightNodes(); } if (nonNullish(this.leftValue) || nonNullish(this.rightValue) || !skipEmpty) { yield this; } if (this.rightTree) { yield* this.rightTree.leftToRightNodes(); } } *rightToLeftNodes(skipEmpty = true) { if (this.rightTree) { yield* this.rightTree.rightToLeftNodes(); } if (nonNullish(this.leftValue) || nonNullish(this.rightValue) || !skipEmpty) { yield this; } if (this.leftTree) { yield* this.leftTree.rightToLeftNodes(); } } *leftToRight() { if (this.leftTree) { yield* this.leftTree.leftToRight(); } else if (this.leftValue) { yield this.leftValue; } if (this.rightTree) { yield* this.rightTree.leftToRight(); } else if (this.rightValue) { yield this.rightValue; } } *rightToLeft() { if (this.rightTree) { yield* this.rightTree.rightToLeft(); } else if (this.rightValue) { yield this.rightValue; } if (this.leftTree) { yield* this.leftTree.rightToLeft(); } else if (this.leftValue) { yield this.leftValue; } } toString() { const leftString = this.leftTree ? this.leftTree.toString() : this.leftValue; const rightString = this.rightTree ? this.rightTree.toString() : this.rightValue; return `[${String(leftString)},${String(rightString)}]`; } print() { console.log(this.toString()); } } class Vector { direction; amount = 1; constructor(s) { switch (s[0]) { case "R": { this.direction = Direction.EAST; break; } case "L": { this.direction = Direction.WEST; break; } case "U": { this.direction = Direction.NORTH; break; } case "D": { this.direction = Direction.SOUTH; break; } } this.amount = Number(s.slice(1)); } } const flattenVectors = (v) => { return v.reduce( (acc, n) => { for (let d = 0; d < n.amount; d++) { acc.curs.pos.addMut(n.direction); acc.curs.step += 1; acc.res.push({ c: new Vec2(acc.curs.pos), steps: acc.curs.step }); } return acc; }, { res: [], curs: { pos: new Vec2(0, 0), step: 0 } } ).res; }; export { BPlusTree as B, PairTree as P, Vector as V, BinaryTree as a, flattenVectors as f, isNestedPair as i };