Day 21
This commit is contained in:
parent
23bd9622a1
commit
15c44c1f6a
139
21/solution.mjs
Normal file
139
21/solution.mjs
Normal file
@ -0,0 +1,139 @@
|
||||
import { readFileSync } from 'node:fs';
|
||||
|
||||
const input = readFileSync('input', 'utf-8');
|
||||
|
||||
class Monkey {
|
||||
constructor(monkeys, name) {
|
||||
this.monkeys = monkeys;
|
||||
this.name = name;
|
||||
this.value = undefined;
|
||||
this.formulas = [];
|
||||
this.aliases = [];
|
||||
}
|
||||
|
||||
addFormula(left, operator, right) {
|
||||
this.formulas.push([left, operator, right]);
|
||||
return this;
|
||||
}
|
||||
|
||||
removeFormulasInvolving(name) {
|
||||
this.formulas = this.formulas.filter(
|
||||
([left, _, right]) => left !== name && right !== name
|
||||
);
|
||||
return this;
|
||||
}
|
||||
|
||||
addAlias(name) {
|
||||
this.aliases.push(name);
|
||||
return this;
|
||||
}
|
||||
|
||||
setValue(value) {
|
||||
this.value = value;
|
||||
return this;
|
||||
}
|
||||
|
||||
solve(path = []) {
|
||||
if (this.value !== undefined) {
|
||||
return this.value;
|
||||
}
|
||||
for (const name of this.aliases) {
|
||||
if (path.includes(name)) {
|
||||
continue;
|
||||
}
|
||||
const value = this.monkeys[name].solve([...path, this.name]);
|
||||
if (value !== 'UNKNOWN') {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
for (const [left, operator, right] of this.formulas) {
|
||||
if (path.includes(left) || path.includes(right)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const leftValue = this.monkeys[left].solve([...path, this.name]);
|
||||
const rightValue = this.monkeys[right].solve([...path, this.name]);
|
||||
|
||||
if (leftValue === 'UNKNOWN' || rightValue === 'UNKNOWN') {
|
||||
continue;
|
||||
}
|
||||
|
||||
switch (operator) {
|
||||
case '*': return leftValue * rightValue;
|
||||
case '/': return leftValue / rightValue;
|
||||
case '+': return leftValue + rightValue;
|
||||
case '-': return leftValue - rightValue;
|
||||
}
|
||||
}
|
||||
return 'UNKNOWN';
|
||||
}
|
||||
}
|
||||
|
||||
const monkeys = {};
|
||||
function getMonkey(name) {
|
||||
if (!monkeys.hasOwnProperty(name)) {
|
||||
monkeys[name] = new Monkey(monkeys, name)
|
||||
}
|
||||
return monkeys[name];
|
||||
}
|
||||
|
||||
input
|
||||
.split('\n')
|
||||
.filter(line => !!line.trim())
|
||||
.forEach(line => {
|
||||
const match = line.match(/^(\w+):\s+(.+?)\s*$/);
|
||||
if (!match) {
|
||||
throw new Error(`Invalid monkey: ${line}`);
|
||||
}
|
||||
const name = match[1];
|
||||
const job = match[2];
|
||||
|
||||
if (/^\d+$/.test(job)) {
|
||||
getMonkey(name).setValue(parseInt(job));
|
||||
} else {
|
||||
const match = job.match(/^(\w+)\s*([*\/+\-=])\s*(\w+)$/);
|
||||
if (!match) {
|
||||
throw new Error(`Invalid formula: ${formula}`);
|
||||
}
|
||||
const left = match[1];
|
||||
const operator = match[2];
|
||||
const right = match[3];
|
||||
|
||||
switch (operator) {
|
||||
case '*':
|
||||
getMonkey(name).addFormula(left, '*', right);
|
||||
getMonkey(left).addFormula(name, '/', right);
|
||||
getMonkey(right).addFormula(name, '/', left);
|
||||
break;
|
||||
case '/':
|
||||
getMonkey(name).addFormula(left, '/', right);
|
||||
getMonkey(left).addFormula(name, '*', right);
|
||||
getMonkey(right).addFormula(left, '/', name);
|
||||
break;
|
||||
case '-':
|
||||
getMonkey(name).addFormula(left, '-', right);
|
||||
getMonkey(left).addFormula(name, '+', right);
|
||||
getMonkey(right).addFormula(left, '-', name);
|
||||
break;
|
||||
case '+':
|
||||
getMonkey(name).addFormula(left, '+', right);
|
||||
getMonkey(left).addFormula(name, '-', right);
|
||||
getMonkey(right).addFormula(name, '-', left);
|
||||
break;
|
||||
default:
|
||||
throw new Error(`Invalid operator: ${operator}`);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
const rootYells = monkeys['root'].solve();
|
||||
console.log('The root monkey will yell:', rootYells);
|
||||
|
||||
for (const monkey of Object.values(monkeys)) {
|
||||
monkey.removeFormulasInvolving('root');
|
||||
}
|
||||
const {0: left, 2: right} = monkeys['root'].formulas[0];
|
||||
monkeys[left].addAlias(right);
|
||||
monkeys[right].addAlias(left);
|
||||
const humnYells = monkeys['humn'].setValue(undefined).solve();
|
||||
console.log('To pass roots equality test, yell:', humnYells);
|
Loading…
Reference in New Issue
Block a user