diff options
Diffstat (limited to '2022/21-Monkey-Math/second.js')
-rw-r--r-- | 2022/21-Monkey-Math/second.js | 127 |
1 files changed, 127 insertions, 0 deletions
diff --git a/2022/21-Monkey-Math/second.js b/2022/21-Monkey-Math/second.js new file mode 100644 index 0000000..6932e13 --- /dev/null +++ b/2022/21-Monkey-Math/second.js @@ -0,0 +1,127 @@ +import * as fs from "fs"; + +const simple = /(\w+): (\d+)/; +const operation = /(\w+): (\w+) ([+\-*/]) (\w+)/; + +class Monkey { + constructor(line) { + // left and right are temporarily strings + this.left = null; + this.right = null; + this.up = null; + const s = line.match(simple); + if (s) { + this.name = s[1]; + this.value = BigInt(s[2]); + } else { + const o = line.match(operation); + if (!o) throw "wtf"; + this.name = o[1]; + this.left = o[2]; + this.operation = o[3]; + this.right = o[4]; + this.value = undefined; + } + } + solve(m, input) { + if (this.name === "humn") { + throw "unreachable humn"; + } + if (this.value !== undefined) { + console.log (this.name, " = ", this.value); + return this.value; + } + switch(m) { + case this.up: return this.solveUp(input); + case this.left: return this.solveLeft(input); + case this.right: return this.solveRight(input); + default: throw "unreachable"; + } + } + solveUp(input) { + if (this.name === "root") { + throw "unreachable"; + } + const left = input[this.left].solve(this.name, input); + const right = input[this.right].solve(this.name, input); + console.log("UP\t", this.name, " = ", this.left, "(", left, ") ", this.operation, " ", this.right, " (", right, ")"); + switch(this.operation) { // up = left op right + case "+": return left + right; + case "-": return left - right; + case "*": return left * right; + case "/": return left / right; + default: throw "unreachable"; + } + } + solveLeft(input) { + if (this.name === "root") { + const root = input[this.right].solve(this.name, input); + console.log("root = ", root); + return root; + } + const up = input[this.up].solve(this.name, input); + const right = input[this.right].solve(this.name, input); + console.log("LEFT\t", this.name, "(", up, ") = ", this.left, this.operation, " ", this.right, " (", right, ")"); + switch(this.operation) { // left = up invop right + case "+": return up - right; + case "-": return up + right; + case "*": return up / right; + case "/": return up * right; + default: throw "unreachable"; + } + } + solveRight(input) { + if (this.name === "root") { + const root = input[this.left].solve(this.name, input); + console.log("root = ", root); + return root; + } + const up = input[this.up].solve(this.name, input); + const left = input[this.left].solve(this.name, input); + console.log("RIGHT\t", this.name, "(", up, ") = ", this.left, "(", left, ") ", this.operation, " ", this.right); + switch(this.operation) { // right = up invop right + case "+": return up - left; + case "-": return left - up; + case "*": return up / left; + case "/": return left / up; + default: throw "unreachable"; + } + } + print() { + console.log(this.name, this.value); + } +} + +function load(filename) { + let res = {}; + fs.readFileSync(filename, "utf8") + .trim() + .split("\n") + .forEach(line => { + let m = new Monkey(line); + res[m.name] = m; + }); + Object.values(res).forEach(m => { + if (m.value === undefined) { + res[m.right].up = m.name; + res[m.left].up = m.name; + } + }); + return res; +} + +let example = load("example"); +let input = load("input"); + +function solve(input) { + let h = input["humn"]; + return input[h.up].solve(h.name, input); +} + +const exampleOutput = solve(example); +if (exampleOutput !== 301n) { + console.log("Example failed with " + exampleOutput); + process.exit(1); // eslint-disable-line +} + +console.log(solve(input)); |