This repository has been archived by the owner on Jan 13, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Day25.scala
45 lines (33 loc) · 1.59 KB
/
Day25.scala
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
package adventofcode.solutions
import adventofcode.Definitions.*
import scala.util.Random
@main def Day25 = Day(25) { (input, part) =>
val components = input.toLines.flatMap {
case s"$lhs: $rhs" => rhs.split(" ").toSeq.flatMap(other => Seq(lhs -> other, other -> lhs))
}.groupBy(_._1).view.mapValues(_.map(_._2).toSeq).toMap
val vertices = components.keySet.toIndexedSeq
def randomPath(current: String, history: Map[String, String], random: Random): Set[(String, String)] =
val nexts = components(current).filterNot(history.contains)
if nexts.nonEmpty then
val next = nexts(random.nextInt(nexts.size))
randomPath(next, history + (current -> next) + (next -> current), random)
else
history.toSet.filter(_ < _)
val remove = (0 until 1000).map(new Random(_))
.map(random => randomPath(vertices(random.nextInt(vertices.size)), Map.empty, random))
.sortBy(-_.size)
.take(100)
.foldLeft(Map.empty[(String, String), Int])((counts, add) =>
add.foldLeft(counts)((counts, key) => counts + (key -> (counts.getOrElse(key, 0) + 1)))
).toSeq.sortBy((_, count) => -count).map((t, _) => t).take(3).flatMap(t => Seq(t, t.swap))
def bfs(current: Set[String], history: Set[String]): Int =
if current.nonEmpty then
val newHistory = history ++ current
val newCurrent = current.flatMap(k => components(k).map(k -> _).diff(remove).map(_._2).filterNot(newHistory.contains))
bfs(newCurrent, newHistory)
else
history.size
val size = bfs(Set(components.keySet.head), Set.empty)
part(1) = size * (components.size - size)
part(2) = ""
}