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