diff --git a/2024/src/main/scala/aoc2024/Day19.scala b/2024/src/main/scala/aoc2024/Day19.scala index 4f06b7e..0f9e660 100644 --- a/2024/src/main/scala/aoc2024/Day19.scala +++ b/2024/src/main/scala/aoc2024/Day19.scala @@ -5,8 +5,6 @@ import nmcb.predef.* object Day19 extends AoC: - case class Design(stripes: String) - val (towels: Vector[String], designs: Vector[String]) = val Array(ts, ds) = input.split("\n\n").map(_.trim) (ts.split(',').map(_.trim).toVector, ds.linesIterator.toVector) diff --git a/2024/src/main/scala/aoc2024/Day20.scala b/2024/src/main/scala/aoc2024/Day20.scala index 04cab1e..3149f3a 100644 --- a/2024/src/main/scala/aoc2024/Day20.scala +++ b/2024/src/main/scala/aoc2024/Day20.scala @@ -10,11 +10,16 @@ object Day20 extends AoC: def cheats(path: Vector[Pos], timeframe: Long): Long = @tailrec - def trace(trail: Vector[(Pos,Int)], cheated: Long): Long = + def trace(trail: Vector[(Pos, Int)], cheated: Long): Long = if trail.nonEmpty then - val (from,time) = trail.head - val rest = trail.tail - val saved = rest.flatMap((to,left) => when(from.manhattanDistance(to) <= timeframe)(left - time - from.manhattanDistance(to))) + val (from, time) = trail.head + val rest = trail.tail + + val saved = + rest.flatMap: (to,left) => + val distance = from.manhattanDistance(to) + when(distance <= timeframe)(left - time - distance) + trace(rest, cheated + saved.count(_ >= 100)) else cheated diff --git a/2024/src/main/scala/aoc2024/Day21.scala b/2024/src/main/scala/aoc2024/Day21.scala index d01ea83..a786c03 100644 --- a/2024/src/main/scala/aoc2024/Day21.scala +++ b/2024/src/main/scala/aoc2024/Day21.scala @@ -29,7 +29,7 @@ object Day21 extends AoC: | |""".stripMargin) - val directionButtonBy: Map[Dir,Button] = + val directionButtonBy: Map[Dir, Button] = Map( E -> '>', W -> '<', @@ -56,16 +56,16 @@ object Day21 extends AoC: to -> (moves.count + shortestPathMoves(moves.pos, to, robot)) .count - def shortestPathMoves(from: Pos, to: Pos, robot: Int): Long = cache.memoize(from,to,robot): + def shortestPathMoves(from: Pos, to: Pos, robot: Int): Long = cache.memoize(from, to, robot): Dijkstra - .breadthFirstSearch((from,Vector.empty[Button])): - case (p,pushes) if p == to => Right( + .breadthFirstSearch((from, Vector.empty[Button])): + case (p, pushes) if p == to => Right( if robot < robots then pointerMovesFor(pushes :+ Button.enter, robot + 1) else pushes.length + 1L ) - case (p,code) => Left( + case (p, code) => Left( p.directionTo(to) .filterNot(d => keypadBy(robot).contains(p step d, Button.empty)) .map(d => (p step d, code :+ directionButtonBy(d))) diff --git a/2024/src/main/scala/aoc2024/Day22.scala b/2024/src/main/scala/aoc2024/Day22.scala index 2ff7546..c19d60c 100644 --- a/2024/src/main/scala/aoc2024/Day22.scala +++ b/2024/src/main/scala/aoc2024/Day22.scala @@ -35,10 +35,10 @@ object Day22 extends AoC: def sequence: Seq[Long] = p._1 def price: Long = p._2 - def solve(secrets: Vector[Long]): Long = + def solve(secrets: Vector[Long], nth: Int): Long = secrets .flatMap: initial => - Iterator.iterate(initial, 2001)(_.nextSecret) + Iterator.iterate(initial, nth + 1)(_.nextSecret) .map(_ % 10) .sliding(5) .map: prices => @@ -53,5 +53,5 @@ object Day22 extends AoC: .values .max - override lazy val answer1: Long = numbers.map(initial => Iterator.iterate(initial, 2001)(_.nextSecret).drain).sum - override lazy val answer2: Long = solve(numbers) + override lazy val answer1: Long = numbers.map(initial => Iterator.iterate(initial)(_.nextSecret).nth(2000)).sum + override lazy val answer2: Long = solve(numbers, 2000)