better humn
This commit is contained in:
parent
8ff78c25c2
commit
ef4a4b1e9a
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Reference in New Issue