2022-21 part 2 in js
This commit is contained in:
		
					parent
					
						
							
								7a7a788a11
							
						
					
				
			
			
				commit
				
					
						c5ac62dc9b
					
				
			
		
					 1 changed files with 127 additions and 0 deletions
				
			
		
							
								
								
									
										127
									
								
								2022/21-Monkey-Math/second.js
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										127
									
								
								2022/21-Monkey-Math/second.js
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -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));
 | 
			
		||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue