Day 06
This commit is contained in:
parent
16873b07c8
commit
22c66a4757
2 changed files with 202 additions and 0 deletions
72
src/day06.scala
Normal file
72
src/day06.scala
Normal file
|
|
@ -0,0 +1,72 @@
|
|||
package aoc
|
||||
package day06
|
||||
|
||||
import scala.annotation.tailrec
|
||||
|
||||
val dayNumber = "06"
|
||||
|
||||
@main def part1: Unit =
|
||||
println(part1(loadInput(dayNumber)))
|
||||
|
||||
@main def part2: Unit =
|
||||
println(part2(loadInput(dayNumber)))
|
||||
|
||||
def part1(input: String): String =
|
||||
val (gridMap, guardPos) = parseInput(input)
|
||||
walk(guardPos, Dir.Up, Set())(using gridMap).size.toString
|
||||
|
||||
def part2(input: String): String =
|
||||
val (gridMap, guardPos) = parseInput(input)
|
||||
(walk(guardPos, Dir.Up, Set())(using gridMap) - guardPos)
|
||||
.count((x, y) =>
|
||||
isLoop(guardPos, Dir.Up, Set())(using gridMap + ((x -> y, '#')))
|
||||
)
|
||||
.toString
|
||||
|
||||
def parseInput(input: String): (Map[(Int, Int), Char], (Int, Int)) =
|
||||
val grid = input.split("\n")
|
||||
val coords =
|
||||
for
|
||||
y <- 0 until grid.length
|
||||
x <- 0 until grid.head.length
|
||||
yield (x, y) -> grid(y)(x)
|
||||
val gridMap = coords.toMap
|
||||
val guardPos = coords.collectFirst { case (x, y) -> '^' => (x, y) }.get
|
||||
(gridMap, guardPos)
|
||||
|
||||
enum Dir:
|
||||
case Up, Right, Down, Left
|
||||
def next = this match
|
||||
case Up => Right
|
||||
case Right => Down
|
||||
case Down => Left
|
||||
case Left => Up
|
||||
def move(x: Int, y: Int) = this match
|
||||
case Up => (x, y - 1)
|
||||
case Right => (x + 1, y)
|
||||
case Down => (x, y + 1)
|
||||
case Left => (x - 1, y)
|
||||
|
||||
@tailrec def walk(pos: (Int, Int), dir: Dir, visited: Set[(Int, Int)])(using
|
||||
gridMap: Map[(Int, Int), Char]
|
||||
): Set[(Int, Int)] =
|
||||
val nextPos = dir.move.tupled(pos)
|
||||
gridMap.get(nextPos) match
|
||||
case Some('.' | '^') =>
|
||||
walk(nextPos, dir, visited + pos)
|
||||
case Some('#') => walk(pos, dir.next, visited)
|
||||
case Some(_) => ???
|
||||
case None => visited + pos
|
||||
|
||||
@tailrec def isLoop(pos: (Int, Int), dir: Dir, visited: Set[(Int, Int, Dir)])(
|
||||
using gridMap: Map[(Int, Int), Char]
|
||||
): Boolean =
|
||||
val nextPos = dir.move.tupled(pos)
|
||||
if visited.contains(nextPos :* dir) then true
|
||||
else
|
||||
gridMap.get(nextPos) match
|
||||
case Some('.' | '^') =>
|
||||
isLoop(nextPos, dir, visited + (pos :* dir))
|
||||
case Some('#') => isLoop(pos, dir.next, visited)
|
||||
case Some(_) => ???
|
||||
case None => false
|
||||
Loading…
Add table
Add a link
Reference in a new issue