Created
December 19, 2017 19:41
-
-
Save russwyte/11d15185c174eb3ce57fa3bd69ef2a07 to your computer and use it in GitHub Desktop.
AoC Day 19
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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