This commit is contained in:
Alexander Gehrke 2021-12-12 02:12:44 +01:00
parent be7e1d14de
commit 537ec6de18
3 changed files with 59 additions and 1 deletions

View file

@ -3,4 +3,56 @@ package de.qwertyuiop.aoc.`2021`
import de.qwertyuiop.aoc.lib.* import de.qwertyuiop.aoc.lib.*
import cats.*, cats.implicits.given import cats.*, cats.implicits.given
def day11(using InputSource): Unit = ??? import Vectors.{*, given}
def day11(using InputSource): Unit =
import Octopodes.*
val fieldRaw = inputF(_.map(_ - '0').toVector)(Vector)
val field = (
for
x <- 0 until fieldRaw.size
y <- 0 until fieldRaw(0).size
yield Vec2D(x,y) -> fieldRaw(x)(y)
).toMap
val r = render(fieldRaw.size, fieldRaw(0).size)
val (finalField, finalFlashes) =
(1 to 100).foldLeft((field, 0)){ case ((field, flashes), _) =>
val (newField, newFlashes) = energize(field)
(newField, flashes + newFlashes)
}
println(s"After $finalFlashes flashes:")
r(finalField)
val inSync = findSync(field, 0)
println(s"In sync after $inSync steps")
object Octopodes:
def render(xSize: Int, ySize: Int)(field: Map[Vec2D[Int], Int]) =
for x <- 0 until xSize do
for y <- 0 until ySize do
print(field(Vec2D(x,y)).toHexString)
println()
def energize(f: Map[Vec2D[Int], Int]): (Map[Vec2D[Int], Int], Int) =
@annotation.tailrec
def flashOctopodes(f: Map[Vec2D[Int], Int], flashed: Set[Vec2D[Int]]): (Map[Vec2D[Int], Int], Int) =
val flashing = f.filter((coord, v) => v > 9).keySet &~ flashed
if flashing.isEmpty then
(f.view.mapValues(v => if v > 9 then 0 else v).toMap, flashed.size + flashing.size)
else
val neighs = flashing.toVector.flatMap(_.neighbours).occurrences
val newF = f.map((coord, v) => coord -> (
if v > 9 || flashing.contains(coord) then 12
else (v + neighs.getOrElse(coord, 0)).min(11)
))
flashOctopodes(newF, flashed | flashing)
flashOctopodes(f.mapValuesS(_ + 1), Set.empty)
def findSync(f: Map[Vec2D[Int], Int], step: Int): Int =
val (newField, newFlashes) = energize(f)
if newFlashes == f.size then step + 1
else findSync(newField, step + 1)

View file

@ -9,6 +9,8 @@ extension [A](input: List[A])(using CanEqual[A,A])
case (h, tail @ (_ :: t)) => case (h, tail @ (_ :: t)) =>
h #:: (if keepSeparator then tail else t).split(separator) h #:: (if keepSeparator then tail else t).split(separator)
extension [A](iterable: Iterable[A])
def occurrences: Map[A, Int] = iterable.groupMapReduce(identity)(_ => 1)(_ + _)
/* Using -Yexplicit-nulls isn't really ready for use with the java standard /* Using -Yexplicit-nulls isn't really ready for use with the java standard
* library. e.g. String doesn't have `@NotNull` annotations for its methods * library. e.g. String doesn't have `@NotNull` annotations for its methods

View file

@ -99,6 +99,10 @@ object Vectors:
neighs neighs
case Some(neighs) => neighs.asInstanceOf[Vector[Vector[T]]] case Some(neighs) => neighs.asInstanceOf[Vector[Vector[T]]]
extension[A](v: IndexedSeq[IndexedSeq[A]]) def get(p: Vec2D[Int]): A = v(p.x)(p.y)
extension[A](v: IndexedSeq[IndexedSeq[IndexedSeq[A]]]) def get(p: Vec3D[Int]): A = v(p.x)(p.y)(p.z)
extension[A](v: IndexedSeq[IndexedSeq[IndexedSeq[IndexedSeq[A]]]]) def get(p: Vec4D[Int]): A = v(p.x)(p.y)(p.z)(p.w)
object Directions: object Directions:
opaque type Dir = Int opaque type Dir = Int
val East: Dir = 0 val East: Dir = 0