better humn

This commit is contained in:
eleith 2023-01-14 08:22:34 -08:00
parent 8ff78c25c2
commit ef4a4b1e9a
1 changed files with 33 additions and 47 deletions

View File

@ -43,7 +43,7 @@ function parseJobs(lines: string[]): MonkeyJobs {
jobs[monkeyName] = {
value: parseInt(job, 10),
type: 'number',
}
} as MonkeyJobNumber
} else if (jobTypeMathMatch.test(job)) {
const jobMath = job.match(jobTypeMathMatch)
if (jobMath) {
@ -54,7 +54,7 @@ function parseJobs(lines: string[]): MonkeyJobs {
operand,
right: rightMonkeyName,
type: 'math',
} as MonkeyJob
} as MonkeyJobMath
} else {
throw new Error(`Invalid math job: ${job}`)
}
@ -75,14 +75,14 @@ function solveJobFor(monkey: string, monkeyJobs: MonkeyJobs): number {
} else if (monkeyJob.type === 'math') {
const leftValue = solveJobFor(monkeyJob.left, monkeyJobs)
const rightValue = solveJobFor(monkeyJob.right, monkeyJobs)
return math(leftValue, monkeyJob.operand, rightValue)
return calculate(leftValue, monkeyJob.operand, rightValue)
}
}
throw new Error(`no job for monkey: ${monkey}`)
}
function math(left: number, operand: Operands, right: number): number {
function calculate(left: number, operand: Operands, right: number): number {
switch (operand) {
case '+':
return left + right
@ -101,78 +101,64 @@ function getAlgorithmFor(
monkeyJob: MonkeyJob,
monkeyJobs: MonkeyJobs
): string | number | MonkeyEquation {
if (monkeyJob.type !== 'math') {
return monkeyJob.value
} else if (monkeyJob.type === 'math') {
const operand = monkeyJob.operand
const leftMonkey = monkeyJobs[monkeyJob.left]
const rightMonkey = monkeyJobs[monkeyJob.right]
const left = getAlgorithmFor(leftMonkey, monkeyJobs)
const right = getAlgorithmFor(rightMonkey, monkeyJobs)
if (monkeyJob.type === 'math') {
const { operand, left, right } = monkeyJob
const leftAlgo = getAlgorithmFor(monkeyJobs[left], monkeyJobs)
const rightAlgo = getAlgorithmFor(monkeyJobs[right], monkeyJobs)
if (typeof left === 'number') {
if (typeof right === 'number') {
return math(left, operand, right)
if (typeof leftAlgo === 'number') {
if (typeof rightAlgo === 'number') {
return calculate(leftAlgo, operand, rightAlgo)
}
return [left, operand, right]
} else if (typeof right === 'number') {
return [left, operand, right]
return [leftAlgo, operand, rightAlgo]
} else if (typeof rightAlgo === 'number') {
return [leftAlgo, operand, rightAlgo]
}
} else {
return monkeyJob.value
}
throw new Error(`too many dependencies for: ${monkeyJob}`)
}
function solveForX(equation: MonkeyEquation, x: number): number {
const left = equation[0]
const operand = equation[1]
const right = equation[2]
function solve(equation: string | MonkeyEquation, equals: number): number {
const [left, operand, right] = equation
let solve = 1
if (typeof equation === 'string') {
return equals
}
// left + right = x -> right = x - left -> left = x - right
// left - right = x -> right = left - x -> left = x + right
// left * right = x -> right = x / left -> left = x / right
// left / right = x -> right = left / x -> left = x * right
if (typeof left === 'number') {
if (typeof left === 'number' && typeof right !== 'number') {
switch (operand) {
case '+':
solve = x - left
break
return solve(right, equals - left)
case '-':
solve = left - x
break
return solve(right, left - equals)
case '*':
solve = x / left
break
return solve(right, equals / left)
default:
solve = left / x
return solve(right, left / equals)
}
} else if (typeof right === 'number') {
} else if (typeof right === 'number' && typeof left !== 'number') {
switch (operand) {
case '+':
solve = x - right
break
return solve(left, equals - right)
case '-':
solve = x + right
break
return solve(left, equals + right)
case '*':
solve = x / right
break
return solve(left, equals / right)
default:
solve = x * right
return solve(left, equals * right)
}
}
if (Array.isArray(right)) {
return solveForX(right, solve)
} else if (Array.isArray(left)) {
return solveForX(left, solve)
}
return solve
throw new Error(`invalid equation: ${equation}`)
}
function solvePart1(lines: string[]): number {
@ -190,7 +176,7 @@ function solvePart2(lines: string[]): number {
const rootAlgo = getAlgorithmFor({ ...root, operand: '-' }, monkeyJobs)
if (Array.isArray(rootAlgo)) {
return solveForX(rootAlgo, 0)
return solve(rootAlgo, 0)
}
}