Skip to content

Commit

Permalink
⚡️cache walking paths
Browse files Browse the repository at this point in the history
  • Loading branch information
twentylemon committed Dec 7, 2024
1 parent 49a0149 commit d751d1b
Showing 1 changed file with 23 additions and 9 deletions.
32 changes: 23 additions & 9 deletions src/main/scala/org/lemon/advent/year2024/Day06.scala
Original file line number Diff line number Diff line change
Expand Up @@ -21,19 +21,33 @@ private object Day06:
val start = grid.find(_._2 == '^').get._1
walk(grid, start, Direction('^')).size

type Paths = Map[Coord, Map[Direction, Coord]]
def routes(grid: Map[Coord, Char]): Paths =
val paths =
for
(start, ch) <- grid.iterator
if ch != '#'
dir <- Direction.values
yield
val end = Iterator.iterate(start)(_ + dir)
.find(coord => !grid.contains(coord) || grid(coord) == '#')
.get
start -> (dir -> (if !grid.contains(end) then end else end - dir))
paths.toSeq.groupBy(_._1).mapValues(_.map(_._2).toMap).toMap

@annotation.tailrec
def isLoop(grid: Map[Coord, Char], cameFrom: Coord, dir: Direction, seen: Set[(Coord, Direction)] = Set()): Boolean =
val goingTo = cameFrom + dir
if !grid.contains(goingTo) then false
else if seen.contains((goingTo, dir)) then true
def isLoop(paths: Paths, wall: Coord)(at: Coord, dir: Direction, seen: Set[(Coord, Direction)] = Set()): Boolean =
if seen.contains((at, dir)) then true
else if !paths.contains(at) then false
else
grid(goingTo) match
case '#' => isLoop(grid, cameFrom, dir.turnRight, seen + ((cameFrom, dir)))
case _ => isLoop(grid, goingTo, dir, seen)
val dest = paths(at)(dir)
if dest == wall || at.directionTo(wall).contains(dir) && dest.directionTo(wall).contains(dir.turnAround) then
isLoop(paths, wall)(wall - dir, dir.turnRight, seen + ((at, dir)))
else isLoop(paths, wall)(dest, dir.turnRight, seen + ((at, dir)))

def part2(input: String) =
val grid = parse(input)
val paths = routes(grid)
val start = grid.find(_._2 == '^').get._1
val dir = Direction('^')
val path = walk(grid, start, dir)
path.par.count(c => isLoop(grid + (c -> '#'), start, dir))
walk(grid, start, dir).count(isLoop(paths, _)(start, dir))

0 comments on commit d751d1b

Please sign in to comment.