From 5899cde85a0959f5806fcc80f48b2189dcfe8fc5 Mon Sep 17 00:00:00 2001 From: Paul-Henri Froidmont Date: Tue, 20 Dec 2022 02:35:18 +0100 Subject: [PATCH] Day 16 --- aoc/resources/day16Input.txt | 50 ++++++++++++++++++++++++ aoc/src/Day16.scala | 76 ++++++++++++++++++++++++++++++++++++ 2 files changed, 126 insertions(+) create mode 100644 aoc/resources/day16Input.txt create mode 100644 aoc/src/Day16.scala diff --git a/aoc/resources/day16Input.txt b/aoc/resources/day16Input.txt new file mode 100644 index 0000000..c256176 --- /dev/null +++ b/aoc/resources/day16Input.txt @@ -0,0 +1,50 @@ +Valve DJ has flow rate=0; tunnels lead to valves ZH, AA +Valve LP has flow rate=0; tunnels lead to valves AA, EE +Valve GT has flow rate=0; tunnels lead to valves FJ, AW +Valve RO has flow rate=5; tunnels lead to valves NO, FD, QV, BV +Valve PS has flow rate=0; tunnels lead to valves FY, UV +Valve QV has flow rate=0; tunnels lead to valves EB, RO +Valve MV has flow rate=0; tunnels lead to valves FL, EB +Valve RN has flow rate=0; tunnels lead to valves AW, LQ +Valve HF has flow rate=0; tunnels lead to valves QN, HW +Valve PY has flow rate=19; tunnel leads to valve SN +Valve AT has flow rate=0; tunnels lead to valves YQ, UY +Valve UY has flow rate=3; tunnels lead to valves KV, ID, AT, PB, PG +Valve YI has flow rate=0; tunnels lead to valves FL, FD +Valve EB has flow rate=8; tunnels lead to valves MV, GQ, QV +Valve ID has flow rate=0; tunnels lead to valves NO, UY +Valve FY has flow rate=15; tunnels lead to valves LQ, PS +Valve GQ has flow rate=0; tunnels lead to valves EB, KM +Valve HW has flow rate=0; tunnels lead to valves FJ, HF +Valve CQ has flow rate=17; tunnels lead to valves KM, GO +Valve AW has flow rate=20; tunnels lead to valves RN, GT, WH, MX +Valve BV has flow rate=0; tunnels lead to valves RO, ZH +Valve PB has flow rate=0; tunnels lead to valves UY, AA +Valve MX has flow rate=0; tunnels lead to valves AW, YG +Valve DE has flow rate=4; tunnels lead to valves MM, PZ, PG, DS, EP +Valve AA has flow rate=0; tunnels lead to valves EP, PB, LP, JT, DJ +Valve QN has flow rate=23; tunnels lead to valves SN, HF +Valve GO has flow rate=0; tunnels lead to valves CQ, MK +Valve PZ has flow rate=0; tunnels lead to valves IJ, DE +Valve PG has flow rate=0; tunnels lead to valves UY, DE +Valve FL has flow rate=18; tunnels lead to valves MV, YI +Valve DS has flow rate=0; tunnels lead to valves DE, ZH +Valve ZH has flow rate=11; tunnels lead to valves YQ, BV, DJ, DS, SB +Valve KV has flow rate=0; tunnels lead to valves UY, IJ +Valve UV has flow rate=9; tunnels lead to valves MM, PS, YG +Valve WH has flow rate=0; tunnels lead to valves JT, AW +Valve FD has flow rate=0; tunnels lead to valves YI, RO +Valve FJ has flow rate=24; tunnels lead to valves HW, GT +Valve JT has flow rate=0; tunnels lead to valves AA, WH +Valve SN has flow rate=0; tunnels lead to valves PY, QN +Valve KM has flow rate=0; tunnels lead to valves GQ, CQ +Valve LQ has flow rate=0; tunnels lead to valves RN, FY +Valve NO has flow rate=0; tunnels lead to valves ID, RO +Valve SB has flow rate=0; tunnels lead to valves ZH, IJ +Valve MK has flow rate=25; tunnel leads to valve GO +Valve YG has flow rate=0; tunnels lead to valves MX, UV +Valve IJ has flow rate=16; tunnels lead to valves EE, KV, PZ, SB +Valve EP has flow rate=0; tunnels lead to valves AA, DE +Valve MM has flow rate=0; tunnels lead to valves UV, DE +Valve YQ has flow rate=0; tunnels lead to valves AT, ZH +Valve EE has flow rate=0; tunnels lead to valves LP, IJ \ No newline at end of file diff --git a/aoc/src/Day16.scala b/aoc/src/Day16.scala new file mode 100644 index 0000000..17b3d82 --- /dev/null +++ b/aoc/src/Day16.scala @@ -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