Clean up day 21

This commit is contained in:
Natsu Kagami 2023-12-22 15:04:30 +01:00
parent cc3e84d95e
commit ad6a55720a
Signed by: nki
GPG key ID: 55A032EB38B49ADB

View file

@ -20,11 +20,6 @@ def inside(x: Int, y: Int) =
def walkable(x: Int, y: Int) = inside(x, y) && board(x)(y) != '#' def walkable(x: Int, y: Int) = inside(x, y) && board(x)(y) != '#'
def getInf(x: Int, y: Int) =
def mod(x: Int, m: Int): Int = if x < 0 then mod(x % m + m, m) else x % m
board(mod(x, board.size))(mod(y, board(0).size))
def walkableInf(x: Int, y: Int) = getInf(x, y) != '#'
// part 1 // part 1
def walk(steps: Int, starting: Set[(Int, Int)]): Set[(Int, Int)] = def walk(steps: Int, starting: Set[(Int, Int)]): Set[(Int, Int)] =
@ -34,11 +29,11 @@ def walk(steps: Int, starting: Set[(Int, Int)]): Set[(Int, Int)] =
val ns = val ns =
starting starting
.flatMap((a, b) => Dir.all.map(_(a, b))) .flatMap((a, b) => Dir.all.map(_(a, b)))
.filter(walkableInf(_, _)) .filter(walkable(_, _))
walk(steps - 1, ns) walk(steps - 1, ns)
def part1 = def part1 =
val possible = walk(300, Set(startPoint)) val possible = walk(64, Set(startPoint))
println(possible.size) println(possible.size)
// part 2 // part 2
@ -107,14 +102,7 @@ def pointsReachable(steps: Int): Long =
else else
val (stx, sty) = startWhere(dx, dy) val (stx, sty) = startWhere(dx, dy)
val dists = shortestPathsFrom(stx, sty)((steps - dToBoard).toInt % 2) val dists = shortestPathsFrom(stx, sty)((steps - dToBoard).toInt % 2)
val res = dists.sortedCountUntil(steps - dToBoard.toInt).toLong dists.sortedCountUntil(steps - dToBoard.toInt).toLong
// println(s"got $dx $dy $dToBoard $stx $sty => $res ${shortestPathsFrom(stx, sty).map(_.size).toSeq}")
res
(-1 to 1).zip((-1 to 1)).foreach { (dx, dy) =>
val (stx, sty) = startWhere(dx, dy)
// println(s"$dx $dy ${shortestPathsFrom(stx, sty).map(_.size).toSeq}")
}
extension (arr: Array[Int]) extension (arr: Array[Int])
def sortedCountUntil(max: Int) = def sortedCountUntil(max: Int) =
@ -122,9 +110,7 @@ def pointsReachable(steps: Int): Long =
var hi = arr.size var hi = arr.size
while low < hi do while low < hi do
val mid = (low + hi) / 2 val mid = (low + hi) / 2
// println(s"$mid => ${arr(mid)} ~ $max")
if arr(mid) <= max then low = mid + 1 else hi = mid if arr(mid) <= max then low = mid + 1 else hi = mid
// println(s"found $low => ${arr(low - 1)}")
low low
((0 to steps).toIterator ((0 to steps).toIterator
@ -143,11 +129,6 @@ def pointsReachable(steps: Int): Long =
val odd = ((steps - baseDistance) % 2).toInt val odd = ((steps - baseDistance) % 2).toInt
val a = (1L until maxRightAllBoard by 2).size * shortestPathsFrom(stx, sty)(odd).size val a = (1L until maxRightAllBoard by 2).size * shortestPathsFrom(stx, sty)(odd).size
val b = (2L until maxRightAllBoard by 2).size * shortestPathsFrom(stx, sty)((board.size + odd) % 2).size val b = (2L until maxRightAllBoard by 2).size * shortestPathsFrom(stx, sty)((board.size + odd) % 2).size
// println(
// s"$dx => $maxRightAllBoard [${distToRow(dx) + distToCol(maxRightAllBoard)} ${shortestPathsFrom(stx, sty)
// .map(_.last)
// .max}] ${a + b}"
// )
val rest = (maxRightAllBoard to steps).toIterator val rest = (maxRightAllBoard to steps).toIterator
.takeWhile(dRow + distToCol(_) <= steps) .takeWhile(dRow + distToCol(_) <= steps)
.map(countWhere(steps, dx, _)) .map(countWhere(steps, dx, _))
@ -160,11 +141,9 @@ def pointsReachable(steps: Int): Long =
else else
val maxLeftAllBoard = val maxLeftAllBoard =
((steps - baseDistance - shortestPathsFrom(stx, sty).map(_.last).max) / board.size).toInt.max(0) + 1 ((steps - baseDistance - shortestPathsFrom(stx, sty).map(_.last).max) / board.size).toInt.max(0) + 1
// println(s"$dx => -$maxLeftAllBoard")
val odd = ((steps - baseDistance) % 2).toInt val odd = ((steps - baseDistance) % 2).toInt
val a = (-1L until -maxLeftAllBoard by -2).size * shortestPathsFrom(stx, sty)(odd).size val a = (-1L until -maxLeftAllBoard by -2).size * shortestPathsFrom(stx, sty)(odd).size
val b = (-2L until -maxLeftAllBoard by -2).size * shortestPathsFrom(stx, sty)((board.size + odd) % 2).size val b = (-2L until -maxLeftAllBoard by -2).size * shortestPathsFrom(stx, sty)((board.size + odd) % 2).size
// println(s"$dx => -$maxLeftAllBoard [${distToRow(dx) + distToCol(-maxLeftAllBoard)}] ${a + b}")
val rest = (-maxLeftAllBoard to -steps by -1).toIterator val rest = (-maxLeftAllBoard to -steps by -1).toIterator
.takeWhile(dRow + distToCol(_) <= steps) .takeWhile(dRow + distToCol(_) <= steps)
.map(countWhere(steps, dx, _)) .map(countWhere(steps, dx, _))
@ -176,18 +155,7 @@ def pointsReachable(steps: Int): Long =
def part2 = def part2 =
val inputs = Seq(26501365) val inputs = Seq(26501365)
// val inputs = Seq(1, 131)
println(inputs.map(pointsReachable)) println(inputs.map(pointsReachable))
// val s = walk(200, Set(startPoint))
// // divide by quadrant
// val quads = s.toSeq
// .groupBy((x, y) =>
// val qx = if x < 0 then -(-x + board.size - 1) / board.size else x / board.size
// val qy = if y < 0 then -(-y + board(0).size - 1) / board(0).size else y / board(0).size
// (qx, qy)
// )
// .mapValues(_.size)
// println((quads.toSeq, quads.values.sum))
@main def Day21(part: Int) = part match @main def Day21(part: Int) = part match
case 1 => part1 case 1 => part1