Skip to content

Commit d3401e9

Browse files
committed
Extract Kruskal to library
1 parent ea8d153 commit d3401e9

File tree

2 files changed

+24
-21
lines changed

2 files changed

+24
-21
lines changed

src/main/scala/eu/sim642/adventofcode2025/Day8.scala

Lines changed: 5 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,8 @@
11
package eu.sim642.adventofcode2025
22

3-
import eu.sim642.adventofcodelib.pos.Pos3
43
import eu.sim642.adventofcodelib.IteratorImplicits.*
5-
import eu.sim642.adventofcodelib.UnionFind
6-
7-
import scala.annotation.tailrec
4+
import eu.sim642.adventofcodelib.graph.Kruskal
5+
import eu.sim642.adventofcodelib.pos.Pos3
86

97
object Day8 {
108

@@ -29,11 +27,7 @@ object Day8 {
2927

3028
def multiplySizesAfter(junctionBoxes: Seq[Pos3], after: Int = 1000, sizes: Int = 3): Int = {
3129
val closestPairs = closestPairsSeq(junctionBoxes)
32-
33-
val ufAfter = closestPairs.iterator
34-
.scanLeft(new UnionFind(junctionBoxes))({ case (uf, (p1, p2)) =>
35-
uf.unioned(p1, p2)
36-
})(after)
30+
val (ufAfter, _) = Kruskal.iterate(junctionBoxes, closestPairs)(after)
3731

3832
ufAfter.groups()
3933
.map(_.size)
@@ -45,18 +39,8 @@ object Day8 {
4539
// TODO: deduplicate
4640
def multiplyLastXs(junctionBoxes: Seq[Pos3]): Int = {
4741
val closestPairs = closestPairsSeq(junctionBoxes)
48-
49-
// TODO: clean up
50-
val size = junctionBoxes.size
51-
val ufAfter = closestPairs.iterator
52-
.scanLeft((new UnionFind(junctionBoxes), 0))({ case ((uf, edges), (p1, p2)) =>
53-
if (uf.sameRepr(p1, p2))
54-
(uf, edges)
55-
else
56-
(uf.unioned(p1, p2), edges + 1)
57-
}).tail.zip(closestPairs).find(_._1._2 == size - 1).get._2
58-
59-
ufAfter._1.x * ufAfter._2.x
42+
val lastPair = Kruskal.iterateEdges(junctionBoxes, closestPairs).last
43+
lastPair._1.x * lastPair._2.x
6044
}
6145

6246
def parseJunctionBox(s: String): Pos3 = s match {
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
package eu.sim642.adventofcodelib.graph
2+
3+
import eu.sim642.adventofcodelib.UnionFind
4+
5+
object Kruskal {
6+
7+
def iterate[A](nodes: Seq[A], sortedEdges: IterableOnce[(A, A)]): Iterator[(UnionFind[A], Option[(A, A)])] = {
8+
sortedEdges.iterator
9+
.scanLeft((new UnionFind(nodes), Option.empty[(A, A)]))({ case ((uf, _), edge@(p1, p2)) =>
10+
if (uf.sameRepr(p1, p2))
11+
(uf, None)
12+
else
13+
(uf.unioned(p1, p2), Some(edge))
14+
})
15+
}
16+
17+
def iterateEdges[A](nodes: Seq[A], sortedEdges: IterableOnce[(A, A)]): Iterator[(A, A)] =
18+
iterate(nodes, sortedEdges).flatMap(_._2).take(nodes.size - 1)
19+
}

0 commit comments

Comments
 (0)