Compare commits
2 Commits
cdf14fdada
...
6db15ba9af
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6db15ba9af | ||
|
|
58710aca7a |
@@ -22,7 +22,8 @@ val solvers = Map[Int, Solver](
|
||||
17 -> Day17,
|
||||
18 -> Day18,
|
||||
19 -> Day19,
|
||||
20 -> Day20
|
||||
20 -> Day20,
|
||||
21 -> Day21
|
||||
)
|
||||
|
||||
def runSolver(solver: Solver, input: os.Path): Unit =
|
||||
|
||||
@@ -20,18 +20,18 @@ object Day20 extends Solver(20):
|
||||
|
||||
def cheats(radius: Int): Int =
|
||||
trace.indices.par
|
||||
.map(a =>
|
||||
(a + 1 until trace.length)
|
||||
.count(b =>
|
||||
val (from, fromDist) = (trace(a), trace.length - a)
|
||||
val (to, toDist) = (trace(b), trace.length - b)
|
||||
.map(toDist =>
|
||||
(toDist + 100 until trace.length)
|
||||
.count(fromDist =>
|
||||
val from = trace(toDist)
|
||||
val to = trace(fromDist)
|
||||
val dist = (from - to).manhattan
|
||||
|
||||
dist <= radius && (fromDist - toDist >= 100 + dist)
|
||||
)
|
||||
)
|
||||
.sum
|
||||
|
||||
|
||||
val p1 = timed { cheats(2) }
|
||||
val p2 = timed { cheats(20) }
|
||||
|
||||
|
||||
48
aoc/src/dev/ctsk/aoc/days/Day21.scala
Normal file
48
aoc/src/dev/ctsk/aoc/days/Day21.scala
Normal 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
2
data/21.ans
Normal file
@@ -0,0 +1,2 @@
|
||||
202274
|
||||
245881705840972
|
||||
5
data/21.in
Normal file
5
data/21.in
Normal file
@@ -0,0 +1,5 @@
|
||||
319A
|
||||
670A
|
||||
349A
|
||||
964A
|
||||
586A
|
||||
Reference in New Issue
Block a user