Skip to content

Commit 7e9a90c

Browse files
committed
Solve 2024 day 5 part 2
1 parent 690181d commit 7e9a90c

File tree

2 files changed

+44
-0
lines changed

2 files changed

+44
-0
lines changed

src/main/scala/eu/sim642/adventofcode2024/Day5.scala

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
package eu.sim642.adventofcode2024
22

3+
import scala.annotation.tailrec
4+
35
object Day5 {
46

57
type Rule = (Int, Int)
@@ -23,6 +25,33 @@ object Day5 {
2325
.sum
2426
}
2527

28+
def sort(rules: Seq[Rule], update: Update): Update = {
29+
val updateRules = rules.filter(rule => update.contains(rule._1) && update.contains(rule._2))
30+
val updateRulesMap = updateRules.toSet.groupMap(_._1)(_._2).withDefaultValue(Set.empty)
31+
32+
// TODO: optimize?
33+
@tailrec
34+
def topologicalSort(pages: Set[Int], updateRulesMap: Map[Int, Set[Int]], sortedUpdate: List[Int]): List[Int] = {
35+
pages.find(updateRulesMap(_).isEmpty) match {
36+
case None => sortedUpdate
37+
case Some(before) =>
38+
val newUpdateRulesMap = (updateRulesMap - before).view.mapValues(_ - before).toMap
39+
topologicalSort(pages - before, newUpdateRulesMap, before :: sortedUpdate)
40+
}
41+
}
42+
43+
topologicalSort(update.toSet, updateRulesMap, Nil)
44+
}
45+
46+
def sumIncorrectMiddles(input: Input): Int = {
47+
val Input(rules, updates) = input
48+
updates
49+
.filter(!isCorrect(rules, _))
50+
.map(sort(rules, _))
51+
.map(update => update(update.size / 2))
52+
.sum
53+
}
54+
2655
def parseRule(s: String): Rule = s match {
2756
case s"$x|$y" => (x.toInt, y.toInt)
2857
}
@@ -40,5 +69,6 @@ object Day5 {
4069

4170
def main(args: Array[String]): Unit = {
4271
println(sumCorrectMiddles(parseInput(input)))
72+
println(sumIncorrectMiddles(parseInput(input)))
4373
}
4474
}

src/test/scala/eu/sim642/adventofcode2024/Day5Test.scala

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,4 +51,18 @@ class Day5Test extends AnyFunSuite {
5151
test("Part 1 input answer") {
5252
assert(sumCorrectMiddles(parseInput(input)) == 6051)
5353
}
54+
55+
test("Part 2 examples") {
56+
val input@Input(rules, updates) = parseInput(exampleInput)
57+
58+
assert(sort(rules, updates(3)) == parseUpdate("97,75,47,61,53"))
59+
assert(sort(rules, updates(4)) == parseUpdate("61,29,13"))
60+
assert(sort(rules, updates(5)) == parseUpdate("97,75,47,29,13"))
61+
62+
assert(sumIncorrectMiddles(input) == 123)
63+
}
64+
65+
test("Part 2 input answer") {
66+
assert(sumIncorrectMiddles(parseInput(input)) == 5093)
67+
}
5468
}

0 commit comments

Comments
 (0)