Skip to content

Instantly share code, notes, and snippets.

@russwyte
Created December 19, 2017 19:41
Show Gist options
  • Save russwyte/11d15185c174eb3ce57fa3bd69ef2a07 to your computer and use it in GitHub Desktop.
Save russwyte/11d15185c174eb3ce57fa3bd69ef2a07 to your computer and use it in GitHub Desktop.
AoC Day 19
package advent
class Advent19 extends Advent {
type Grid = Array[Array[Char]]
case class Position(x: Int, y: Int)
sealed trait Move {
def apply(position: Position): Position
}
case object Up extends Move {
def apply(p: Position): Position = p.copy(y = p.y - 1)
}
case object Down extends Move {
def apply(p: Position): Position = p.copy(y = p.y + 1)
}
case object Left extends Move {
def apply(p: Position): Position = p.copy(x = p.x - 1)
}
case object Right extends Move {
def apply(p: Position): Position = p.copy(x = p.x + 1)
}
def charAt(position: Position, grid: Grid) = grid.lift(position.y).flatMap(_.lift(position.x)).getOrElse(' ')
case class State(move: Move, position: Position) {
def apply(grid: Grid): State = {
val c = charAt(position, grid)
if (c == '+') {
move match {
case Down | Up =>
if (charAt(Left(position), grid) != ' ') {
copy(Left, Left(position))
} else {
copy(Right, Right(position))
}
case Right | Left =>
if (charAt(Up(position), grid) != ' ') {
copy(Up, Up(position))
} else {
copy(Down, Down(position))
}
case _ => this
}
} else if (c == ' ') this
else { copy(position = move(position)) }
}
}
object State {
def apply(g: Grid) = new State(Down, Position(g(0).indexOf('|'), 0))
}
def stream(g: Grid): Stream[State] = {
def inner(s: State): Stream[State] = {
val next = s(g)
if (next == s) Stream.empty else s #:: inner(next)
}
inner(State(g))
}
def parse(s: String): Grid = {
s.splitOnNewline.map(_.toCharArray)
}
def part1(s: String) = {
val grid = parse(s)
stream(grid).map(s => charAt(s.position, grid)).filter(_.isLetter).mkString
}
def part2(s: String) = {
val grid = parse(s)
stream(grid).length
}
val sample =
" | \n | +--+ \n A | C \n F---|----E|--+ \n | | | D \n +B-+ +--+ \n"
"part1" should "work" in {
part1(sample) should be("ABCDEF")
part1(Inputs.day19) should be("BPDKCZWHGT")
}
"part2" should "work" in {
part2(sample) should be(38)
part2(Inputs.day19) should be(17728)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment