Skip to content

Instantly share code, notes, and snippets.

@waynejo
Last active June 11, 2021 12:38
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save waynejo/9dbc0594ecc165ada3c126dd550a8a94 to your computer and use it in GitHub Desktop.
Save waynejo/9dbc0594ecc165ada3c126dd550a8a94 to your computer and use it in GitHub Desktop.
import java.io.FileInputStream
import collection.immutable.HashMap
import scala.annotation.tailrec
import scala.io.StdIn
val directionCodes = Vector(("e", 2, 0), ("se", 1, -1), ("sw", -1, -1), ("w", -2, 0), ("nw", -1, 1), ("ne", 1, 1))
case class Point(x: Int = 0, y: Int = 0):
def move(dx: Int, dy: Int): Point =
Point(x + dx, y + dy)
case class Directions(directions: String):
def point(): Point =
@tailrec
def _point(codes: String, acc: Point): Point =
directionCodes.find(code => codes.startsWith(code._1)) match
case Some((word, dx, dy)) =>
_point(codes.drop(word.length), acc.move(dx, dy))
case _ =>
acc
_point(directions, Point())
def blackTilesFromInput(inputs: Vector[String]): Set[Point] = {
inputs.foldLeft(Set[Point]()) { (acc, x) =>
val point = Directions(x).point()
if acc.contains(point) then
acc - point
else
acc + point
}
}
def adjacentWhiteTiles(blacks: Set[Point]): Set[Point] = {
blacks.flatMap(point => directionCodes.map(code => point.move(code._2, code._3))).diff(blacks)
}
def numbefOfAdjacentBlack(blacks: Set[Point], point: Point): Int = {
directionCodes.map(code => point.move(code._2, code._3)).count(blacks.contains)
}
def solve24_1(inputs: Vector[String]): Int = {
blackTilesFromInput(inputs).size
}
def simulateDay(remainDay: Int, blacks: Set[Point]): Int = {
if 0 >= remainDay then
blacks.size
else
val whites = adjacentWhiteTiles(blacks)
val newBlacks = whites.filter(white => 2 == numbefOfAdjacentBlack(blacks, white))
val nextBlacks = blacks.filter(black => Set(1, 2).contains(numbefOfAdjacentBlack(blacks, black))) ++ newBlacks
simulateDay(remainDay - 1, nextBlacks)
}
def solve24_2(inputs: Vector[String]): Int = {
val blacks = blackTilesFromInput(inputs)
simulateDay(100, blacks)
}
@main def solve24() =
val in = new FileInputStream("example24-1.in")
System.setIn(in)
val inputs = Iterator.continually(StdIn.readLine())
.takeWhile(line => null != line && line.trim.nonEmpty)
.toVector
println(solve24_1(inputs)) // 388
println(solve24_2(inputs)) // 4002
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment