This commit is contained in:
Christian
2024-12-21 20:01:19 +01:00
parent 58710aca7a
commit 6db15ba9af
4 changed files with 57 additions and 1 deletions

View File

@@ -22,7 +22,8 @@ val solvers = Map[Int, Solver](
17 -> Day17, 17 -> Day17,
18 -> Day18, 18 -> Day18,
19 -> Day19, 19 -> Day19,
20 -> Day20 20 -> Day20,
21 -> Day21
) )
def runSolver(solver: Solver, input: os.Path): Unit = def runSolver(solver: Solver, input: os.Path): Unit =

View File

@@ -0,0 +1,48 @@
package dev.ctsk.aoc.days
import dev.ctsk.aoc.*
object Day21 extends Solver(21):
private val keyPad = Grid(Array("789", "456", "123", " 0A").map(_.toArray))
private val buttonPad = Grid(Array(" ^A", "<v>").map(_.toArray))
private val paths = Memo(paths_)
private def paths_(args: (Char, Char, Grid[Char])): Array[Array[Char]] =
val (from, to, grid) = args
val Point(fx, fy) = grid.findFirst(_ == from).get
val Point(tx, ty) = grid.findFirst(_ == to).get
val ops = Seq((fx, tx, 'v'), (tx, fx, '^'), (fy, ty, '>'), (ty, fy, '<'))
val seq = ops.flatMap((a, b, c) => (a until b).map(_ => c))
def gap(path: Array[Char]): Boolean =
path
.scanLeft(Point(fx, fy))((acc, c) => Direction.from(c)(acc))
.exists(grid(_).contains(' '))
seq.permutations.map(_.toArray).filterNot(gap).toArray
private def countPresses(codes: Array[String], numRobots: Int): Long =
type State = (Char, Char, Int)
def minCost_(state: State, f: State => Long): Long =
val (from, to, robots) = state
if robots == 0 then return 1
paths(from, to, if robots == numRobots then keyPad else buttonPad)
.map('A' +: _ :+ 'A')
.map(path => path.sliding(2).map(w => f(w(0), w(1), robots - 1)).sum)
.min
val minCost = Memo.Y(minCost_)
def evalCode(line: String): Long =
('A' +: line).sliding(2).map(w => minCost(w(0), w(1), numRobots)).sum
codes.map(code => code.init.toInt * evalCode(code)).sum
override def run(input: os.ReadablePath): (Timings, Solution) =
val codes = os.read.lines(input).toArray
val (p1_time, p1_solution) = timed { countPresses(codes, 3) }
val (p2_time, p2_solution) = timed { countPresses(codes, 26) }
(
Timings(0, p1_time, p2_time),
Solution(Long.box(p1_solution), Long.box(p2_solution))
)

2
data/21.ans Normal file
View File

@@ -0,0 +1,2 @@
202274
245881705840972

5
data/21.in Normal file
View File

@@ -0,0 +1,5 @@
319A
670A
349A
964A
586A