|
1 | 1 | package AdventOfCode2022
|
2 | 2 |
|
3 | 3 | object Day21:
|
4 |
| - def parse(input: Seq[String]): collection.mutable.Map[String, () => Long] = |
| 4 | + def parse(input: Seq[String], part2: Boolean): collection.mutable.Map[String, () => Long] = |
5 | 5 | val monkeys = collection.mutable.Map[String, () => Long]()
|
6 |
| - def compute(name: String): Long = monkeys(name)() |
7 |
| - |
8 | 6 | input.foreach { line =>
|
9 | 7 | val Array(name, rest: _*) = line.split("[: ]+"): @unchecked
|
10 | 8 | monkeys(name) = rest match
|
11 | 9 | case Seq(number) => () => number.toLong
|
12 |
| - case Seq(left, op, right) => op match |
13 |
| - case "+" => () => compute(left) + compute(right) |
14 |
| - case "-" => () => compute(left) - compute(right) |
15 |
| - case "*" => () => compute(left) * compute(right) |
16 |
| - case "/" => () => compute(left) / compute(right) |
| 10 | + case Seq(left, operation, right) => operation match |
| 11 | + case _ if name == "root" && part2 => () => (monkeys(left)() - monkeys(right)()).abs |
| 12 | + case "+" => () => monkeys(left)() + monkeys(right)() |
| 13 | + case "-" => () => monkeys(left)() - monkeys(right)() |
| 14 | + case "*" => () => monkeys(left)() * monkeys(right)() |
| 15 | + case "/" => () => monkeys(left)() / monkeys(right)() |
17 | 16 | }
|
18 |
| - |
19 | 17 | monkeys
|
20 |
| - end parse |
21 | 18 |
|
22 |
| - def part1(input: Seq[String]): Long = parse(input)("root")() |
| 19 | + def part1(input: Seq[String]): Long = parse(input, false)("root")() |
23 | 20 |
|
24 | 21 | def part2(input: Seq[String]): Long =
|
25 |
| - val monkeys = parse(input) |
26 |
| - var start = 3_000_000_000_000L |
27 |
| - var middle = 0L |
28 |
| - var end = 4_000_000_000_000L |
| 22 | + val monkeys = parse(input, true) |
29 | 23 |
|
30 |
| - while (start < end) do { |
31 |
| - val middle = (start + end) / 2 |
| 24 | + def check(n: Long): Long = |
| 25 | + monkeys("humn") = () => n |
| 26 | + monkeys("root")() |
32 | 27 |
|
33 |
| - monkeys("humn") = () => middle |
34 |
| - val result = monkeys("lzfc")() |
35 |
| - val target = monkeys("qrgn")() |
36 |
| - |
37 |
| - if result < target then end = middle - 1 |
38 |
| - else if result > target then start = middle + 1 |
39 |
| - else return middle |
40 |
| - } |
| 28 | + def helper(prev: Long, n: Long, step: Long): Long = |
| 29 | + val next = n + step |
| 30 | + val result = check(next) |
| 31 | + if result == 0 then next |
| 32 | + else if result < prev then helper(result, next, step) |
| 33 | + else helper(result, next, step / -2) |
41 | 34 |
|
42 |
| - -1 |
| 35 | + helper(check(0), 0, 1 << 60) |
43 | 36 | end part2
|
44 | 37 |
|
45 | 38 | def main(args: Array[String]): Unit =
|
|
0 commit comments