Day 14: use direct binary split instead of 2^n calculation

This commit is contained in:
Natsu Kagami 2023-12-14 16:23:15 +01:00
parent f9cc8c2824
commit f3546cfc84
Signed by: nki
GPG key ID: 55A032EB38B49ADB

View file

@ -43,23 +43,17 @@ def part1 =
// part 2 // part 2
object Cycling: object Cycling:
private val memo = mutable.Map.empty[(Board, Int), Board] private val memo = mutable.Map.empty[(Board, Long), Board]
private def getPower(b: Board, p: Int): Board = // b.cycle 2^p times
memo.getOrElseUpdate(
(b, p), {
if p == 0 then b.cycle
else getPower(getPower(b, p - 1), p - 1)
}
)
def apply(b: Board, times: Long): Board = def apply(b: Board, times: Long): Board =
@scala.annotation.tailrec if times == 0 then b
def loop(b: Board, i: Int): Board = else
val pow = 1L << i memo.getOrElseUpdate(
if pow > times then b (b, times), {
else if (pow & times) > 0 then loop(getPower(b, i), i + 1) val twice = apply(apply(b, times / 2), times / 2)
else loop(b, i + 1) if times % 2 == 0 then twice else twice.cycle
loop(b, 0) }
)
def part2 = def part2 =
println(Cycling(board, 1_000_000_000).load) println(Cycling(board, 1_000_000_000).load)