This commit is contained in:
Paul-Henri Froidmont 2022-12-20 02:35:18 +01:00
parent cc7c5b88f0
commit 5899cde85a
Signed by: phfroidmont
GPG key ID: BE948AFD7E7873BE
2 changed files with 126 additions and 0 deletions

76
aoc/src/Day16.scala Normal file
View file

@ -0,0 +1,76 @@
import scala.io.Source
import scala.util.chaining.*
import scala.collection.mutable
object Day16 extends App:
val valves = Source
.fromURL(getClass.getResource("day16Input.txt"))
.mkString
.split('\n')
.map(
_.drop(6)
.replaceAllLiterally("has flow rate=", "")
.replaceAllLiterally("; tunnels lead to valves", "")
.replaceAllLiterally("; tunnel leads to valve", "")
.replaceAllLiterally(",", "")
.split(" ")
)
.map(l => Valve(l.head, l(1).toInt, l.drop(2).toList))
final case class Valve(name: String, rate: Int, tunnels: List[String])
val valvesMap = valves.map(v => (v.name, v)).toMap
val workingValves = valves.filter(_.rate > 0).map(_.name).toList
val distances = mutable.Map.from(
for
valve <- valves
targetValves = valves.map(_.name).map((_, 9999)).to(mutable.Map)
yield (valve.name, targetValves)
)
for
valve <- valves
tunnel <- valve.tunnels
do distances(valve.name)(tunnel) = 1
for
k <- valves.map(_.name)
i <- valves.map(_.name)
j <- valves.map(_.name)
current = distances(i)(j)
dist = distances(i)(k) + distances(k)(j)
if current > dist
do distances(i)(j) = dist
def computeFlow(current: String, rest: List[String], timeLeft: Int): Int =
rest
.filter(distances(current)(_) < timeLeft)
.map(r => (r, rest.filterNot(_ == r)))
.map { case (r, rest) =>
valvesMap(r).rate * (timeLeft - distances(current)(r) - 1) +
computeFlow(r, rest, timeLeft - distances(current)(r) - 1)
}
.prepended(0)
.max
def computeFlow2(current: String, rest: List[String], timeLeft: Int): Int =
rest
.filter(distances(current)(_) < timeLeft)
.map(r => (r, rest.filterNot(_ == r)))
.map { case (r, rest) =>
valvesMap(r).rate * (timeLeft - distances(current)(r) - 1) +
computeFlow2(r, rest, timeLeft - distances(current)(r) - 1)
}
.prepended(computeFlow("AA", rest, 26))
.max
val part1 = computeFlow("AA", workingValves, 30)
println("Part 1:")
println(part1)
val part2 = computeFlow2("AA", workingValves, 26)
println("Part 2:")
println(part2)
end Day16