Day 16
This commit is contained in:
parent
cc7c5b88f0
commit
5899cde85a
2 changed files with 126 additions and 0 deletions
76
aoc/src/Day16.scala
Normal file
76
aoc/src/Day16.scala
Normal 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
|
||||
Loading…
Add table
Add a link
Reference in a new issue