Advent of Code 2022 - Day 21: Monkey Math Solution

Complex number

Part 1

Straightforward recursion to calculate value

Parsed data

1{
2 root: [ 'pppw', '+', 'sjmn' ],
3 dbpl: 5,
4 cczh: [ 'sllz', '+', 'lgvd' ],
5 zczc: 2,
6 ptdq: [ 'humn', '-', 'dvpt' ],
7 dvpt: 3,
8 lfqf: 4,
9 humn: 5,
10 ljgn: 2,
11 sjmn: [ 'drzm', '*', 'dbpl' ],
12 sllz: 4,
13 pppw: [ 'cczh', '/', 'lfqf' ],
14 lgvd: [ 'ljgn', '*', 'ptdq' ],
15 drzm: [ 'hmdt', '-', 'zczc' ],
16 hmdt: 32
17}

Implementation

1const fs = require("fs")
2
3const getFuncFromOperator = operator =>
4 ({
5 "+": (a, b) => a + b,
6 "-": (a, b) => a - b,
7 "*": (a, b) => a * b,
8 "/": (a, b) => a / b,
9 }[operator])
10
11const readData = () => {
12 const data = fs
13 .readFileSync("./input", "utf-8")
14 .split(/\r?\n/)
15 .filter(Boolean)
16 .map(line => line.split(": "))
17 .map(([key, value]) => [
18 key,
19 Number.isNaN(Number(value)) ? value.split(" ") : Number(value),
20 ])
21
22 return Object.fromEntries(data)
23}
24
25const main = () => {
26 const data = readData()
27
28 const recursion = name => {
29 const value = data[name]
30
31 if (Number.isInteger(value)) return value
32
33 const [operand1, operator, operand2] = value
34 const func = getFuncFromOperator(operator)
35
36 return func(recursion(operand1), recursion(operand2))
37 }
38
39 const res = recursion("root")
40
41 console.log(res)
42}
43
44main()

Part 2

Convert to complex number, unknown humn could be store in imaginary part

Parsed data

1{
2 root: [ 'pppw', '+', 'sjmn' ],
3 dbpl: { real: 5, imag: 0 },
4 cczh: [ 'sllz', '+', 'lgvd' ],
5 zczc: { real: 2, imag: 0 },
6 ptdq: [ 'humn', '-', 'dvpt' ],
7 dvpt: { real: 3, imag: 0 },
8 lfqf: { real: 4, imag: 0 },
9 humn: { real: 0, imag: 1 },
10 ljgn: { real: 2, imag: 0 },
11 sjmn: [ 'drzm', '*', 'dbpl' ],
12 sllz: { real: 4, imag: 0 },
13 pppw: [ 'cczh', '/', 'lfqf' ],
14 lgvd: [ 'ljgn', '*', 'ptdq' ],
15 drzm: [ 'hmdt', '-', 'zczc' ],
16 hmdt: { real: 32, imag: 0 }
17}

Recursively calculate lefh-hand side (LHS), right-hand side (RHS) of root and we will get 2 complex numbers

Calculate imaginary from

1LHS = RHS

to get humn value

Operations for complex number could be refered from Wikipedia or any mathemetic blogs

Implementation

1const fs = require("fs")
2
3const getFuncFromOperator = operator =>
4 ({
5 "+": ({ real: x, imag: y }, { real: u, imag: v }) => ({
6 real: x + u,
7 imag: y + v,
8 }),
9 "-": ({ real: x, imag: y }, { real: u, imag: v }) => ({
10 real: x - u,
11 imag: y - v,
12 }),
13 "*": ({ real: x, imag: y }, { real: u, imag: v }) => ({
14 real: x * u - y * v,
15 imag: x * v + y * u,
16 }),
17 "/": ({ real: x, imag: y }, { real: u, imag: v }) => ({
18 real: (x * u + y * v) / (u ** 2 + v ** 2),
19 imag: (y * u - x * v) / (u ** 2 + v ** 2),
20 }),
21 }[operator])
22
23const readData = () => {
24 const data = fs
25 .readFileSync("./input", "utf-8")
26 .split(/\r?\n/)
27 .filter(Boolean)
28 .map(line => line.split(": "))
29 .map(([key, value]) => [
30 key,
31 Number.isNaN(Number(value))
32 ? value.split(" ")
33 : { real: Number(value), imag: 0 },
34 ])
35
36 return Object.fromEntries(data)
37}
38
39const main = () => {
40 const data = readData()
41
42 const recursion = name => {
43 const value = data[name]
44
45 if (!Array.isArray(value)) return value
46
47 const func = getFuncFromOperator(value[1])
48
49 value[0] = recursion(value[0])
50 value[2] = recursion(value[2])
51
52 return func(value[0], value[2])
53 }
54
55 data["humn"] = { real: 0, imag: 1 }
56 recursion("root")
57
58 let [lhs, _, rhs] = data["root"]
59
60 if (rhs.imag) {
61 ;[lhs, rhs] = [rhs, lhs]
62 }
63
64 const res = Math.floor((rhs.real - lhs.real) / lhs.imag)
65
66 console.log(res)
67}
68
69main()

References

Original problem

Complex number (Wikipedia)

Comments

Loading comments...

Tags

adventofcode

recursion

math

Next Post

Advent of Code 2022 - Day 23: Unstable Diffusion

Read the problem description carefully, the rest is straigthforward implementation

Previous Post

HoningJS

Search Posts