@@ -62,39 +62,23 @@ object Day23 {
62
62
}).toMap
63
63
}
64
64
65
- case class HikePos (pos : Pos , path : Set [Pos ])
66
-
67
- val graphTraversal = new GraphTraversal [HikePos ] {
68
- override val startNode : HikePos = HikePos (startPos, Set (startPos))
69
-
70
- override def neighbors (hikePos : HikePos ): IterableOnce [(HikePos , Int )] = {
71
- val HikePos (pos, path) = hikePos
72
- for {
73
- (newPos, dist) <- keyAdjacents.getOrElse(pos, Map .empty)
74
- if ! path.contains(newPos)
75
- } yield HikePos (newPos, path + newPos) -> dist
65
+ // based on https://github.com/glguy/advent/blob/9c27a67f756c44b7f0711539ee5e892dca252791/solutions/src/2023/23.hs
66
+ def helper (pos : Pos , keyAdjacents : Map [Pos , Map [Pos , Int ]], dist : Int ): Int = {
67
+ if (pos == targetPos)
68
+ dist
69
+ else {
70
+ keyAdjacents.get(pos) match {
71
+ case Some (adjacents) =>
72
+ val newKeyAdjacents = keyAdjacents - pos
73
+ (for {
74
+ (toPos, cost) <- adjacents
75
+ } yield helper(toPos, newKeyAdjacents, dist + cost)).max
76
+ case None => 0
77
+ }
76
78
}
77
79
}
78
80
79
- @ tailrec
80
- def helper (todo : Set [HikePos ], distances : Map [HikePos , Int ]): Map [HikePos , Int ] = {
81
- val newTodoDistances = (for {
82
- fromPos <- todo.iterator
83
- fromDist = distances(fromPos)
84
- (toPos, dist) <- graphTraversal.neighbors(fromPos).iterator
85
- toDist = fromDist + dist
86
- if distances.getOrElse(toPos, 0 ) < toDist
87
- } yield toPos -> toDist).groupMapReduce(_._1)(_._2)(_ max _)
88
- val newTodo = newTodoDistances.keySet
89
- val newDistances = distances ++ newTodoDistances
90
- if (newTodo.isEmpty)
91
- newDistances.filter(_._1.pos == targetPos)
92
- else
93
- helper(newTodoDistances.keySet, newDistances)
94
- }
95
-
96
- val distances = helper(Set (graphTraversal.startNode), Map (graphTraversal.startNode -> 0 ))
97
- distances.values.max
81
+ helper(startPos, keyAdjacents, 0 )
98
82
}
99
83
}
100
84
0 commit comments