diff --git a/aoc/src/dev/ctsk/aoc/days/Day11.scala b/aoc/src/dev/ctsk/aoc/days/Day11.scala index 04e52f1..01b6dde 100644 --- a/aoc/src/dev/ctsk/aoc/days/Day11.scala +++ b/aoc/src/dev/ctsk/aoc/days/Day11.scala @@ -1,51 +1,40 @@ package dev.ctsk.aoc.days import dev.ctsk.aoc._ -import scala.collection.mutable +import scala.collection.mutable.{Map => MuMap} object Day11 extends Solver(11): - // upper and lower halves of number - def halves(n: Long): Option[(Long, Long)] = + private def halves(n: Long): Option[(Long, Long)] = val numDigits = (Math.log10(n) + 1).toLong - numDigits % 2 match - case 1 => None - case 0 => { - Some( - ( - n % Math.pow(10, numDigits / 2).toLong, - n / Math.pow(10, numDigits / 2).toLong - ) - ) - } + if numDigits % 2 == 1 then None + else + val mod = Math.pow(10, numDigits / 2).toLong + Some(n % mod, n / mod) - def counter_compute(stones: Array[Long], depth: Long): Long = - var acc: mutable.Map[Long, Long] = - mutable.Map.from(stones.map((_, 1L))) - - for (_ <- 0L until depth) { - val next = mutable.Map.empty[Long, Long].withDefaultValue(0L) - for ((stone, count) <- acc) { + private def count(initial: Seq[Long], depth: Int): Long = + def step(stones: MuMap[Long, Long]): MuMap[Long, Long] = + val next = MuMap.empty[Long, Long].withDefaultValue(0L) + for ((stone, count) <- stones) { if stone == 0 then next(1) += count else - halves(stone.toLong) match + halves(stone) match case Some((a, b)) => next(a) += count next(b) += count case None => next(stone * 2024) += count } - acc = next - } + next - acc.values.sum + val initMap = MuMap.from(initial.map((_, 1L))) + Seq.iterate(initMap, depth + 1)(step).last.values.sum def run(input: os.ReadablePath): (Timings, Solution) = - val in = longs(os.read.lines(input).head).toArray - - val p1 = timed { counter_compute(in, 25) } - val p2 = timed { counter_compute(in, 75) } + val (pre_time, in) = timed { longs(os.read.lines(input).head) } + val (p1_time, p1_solution) = timed { count(in, 25) } + val (p2_time, p2_solution) = timed { count(in, 75) } ( - Timings(0, p1._1, p2._1), - Solution(Long.box(p1._2), Long.box(p2._2)) + Timings(pre_time, p1_time, p2_time), + Solution(Long.box(p1_solution), Long.box(p2_solution)) )