Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 27c7703

Browse files
Inverse method
1 parent cb5b674 commit 27c7703

File tree

2 files changed

+50
-27
lines changed

2 files changed

+50
-27
lines changed

‎src/main/scala/AdventOfCode2022/Day21.scala

Lines changed: 49 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,38 +1,61 @@
11
package AdventOfCode2022
22

33
object Day21:
4-
def parse(input: Seq[String], part2: Boolean): collection.mutable.Map[String, () => Long] =
5-
val monkeys = collection.mutable.Map[String, () => Long]()
6-
input.foreach { line =>
7-
val Array(name, rest: _*) = line.split("[: ]+"): @unchecked
8-
monkeys(name) = rest match
9-
case Seq(number) => () => number.toLong
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)()
4+
sealed trait Monkey
5+
case class Number(value: Long) extends Monkey
6+
case class Operation(left: String, operation: String, right: String) extends Monkey
7+
8+
def parse(input: Seq[String]): Map[String, Monkey] =
9+
input.map {
10+
case s"$name: $left$operation$right" => name -> Operation(left, operation, right)
11+
case s"$name: $value" => name -> Number(value.toLong)
1612
}
17-
monkeys
13+
.toMap
1814

19-
def part1(input: Seq[String]): Long = parse(input, false)("root")()
15+
def calculate(monkeys: Map[String, Monkey]): Map[String, Long] =
16+
val result = collection.mutable.Map[String, Long]()
17+
def compute(name: String) = result.getOrElseUpdate(name, helper(name))
18+
def helper(name: String): Long = monkeys(name) match
19+
case Number(value) => value
20+
case Operation(left, operation, right) => operation match
21+
case "+" => compute(left) + compute(right)
22+
case "-" => compute(left) - compute(right)
23+
case "*" => compute(left) * compute(right)
24+
case "/" => compute(left) / compute(right)
2025

21-
def part2(input: Seq[String]): Long =
22-
val monkeys = parse(input, true)
26+
compute("root")
27+
result.toMap
28+
end calculate
2329

24-
def check(n: Long): Long =
25-
monkeys("humn") = () => n
26-
monkeys("root")()
30+
def part1(input: Seq[String]): Long =
31+
val monkeys = parse(input)
32+
val results = calculate(monkeys)
33+
results("root")
34+
35+
def part2(input: Seq[String]): Long =
36+
val monkeys = parse(input)
37+
val results = calculate(monkeys)
2738

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)
39+
def helper(name: String, value: Long): Option[Long] = monkeys(name) match
40+
case Number(_) => Option.when(name == "humn")(value)
41+
case Operation(left, _, right) if name == "root" =>
42+
val first = helper(right, results(left))
43+
val second = helper(left, results(right))
44+
first.orElse(second)
45+
case Operation(left, operation, right) =>
46+
val first = operation match
47+
case "+" => helper(right, value - results(left))
48+
case "-" => helper(right, results(left) - value)
49+
case "*" => if results(left) != 0 then helper(right, value / results(left)) else None
50+
case "/" => if value != 0 then helper(right, results(left) / value) else None
51+
val second = operation match
52+
case "+" => helper(left, value - results(right))
53+
case "-" => helper(left, value + results(right))
54+
case "*" => if results(right) != 0 then helper(left, value / results(right)) else None
55+
case "/" => helper(left, value * results(right))
56+
first.orElse(second)
3457

35-
helper(check(0), 0, 1<<60)
58+
helper("root", -1).get
3659
end part2
3760

3861
def main(args: Array[String]): Unit =

‎src/test/scala/AdventOfCode2022/Day21Suite.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,5 +25,5 @@ class Day21Suite extends AnyFunSuite:
2525
}
2626

2727
test("Part 2 should handle sample input correctly") {
28-
assert(Day21.part2(sample) == 302)
28+
assert(Day21.part2(sample) == 301)
2929
}

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /