|
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