Files
aoc/scalaAoC/2018/day12/part1.scala
2020-12-03 10:23:51 +01:00

62 lines
1.8 KiB
Scala

import scala.io.StdIn.readLine
val LAST_GEN = 130
case class Rule(m2: Boolean, m1: Boolean, o: Boolean, p1: Boolean, p2: Boolean, r: Boolean) {
def computePot(n: Int, input: Set[Int]): Option[Int] =
if (input.contains(n - 2) == m2 &&
input.contains(n - 1) == m1 &&
input.contains(n) == o &&
input.contains(n + 1) == p1 &&
input.contains(n + 2) == p2 &&
r) {
Some(n)
} else {
None
}
}
def parseRule(in: String): Option[Rule] =
(("(#|\\.)" * 5) + " => (#|\\.)").r.findFirstMatchIn(in).map(
m => Rule(m.group(1) == "#", m.group(2) == "#", m.group(3) == "#", m.group(4) == "#", m.group(5) == "#", m.group(6) == "#")
)
def computeGeneration(current: Set[Int], rules: List[Rule]): Set[Int] =
((current.min - 2).to(current.max + 2))
.flatMap(k => rules.flatMap(_.computePot(k, current)).headOption)
.toSet
def printGeneration(min: Int, max: Int)(gen: (Int, Set[Int])): Unit = gen match {
case (id, pots) =>
val chars = pots.map(k => k -> '#').toMap.withDefaultValue('.')
val str = List.range(min, max, 1).map(chars).mkString("")
val sum = pots.sum
println(s"$id: $str $sum")
}
val initialStateReg = "^initial state: ((?:#|\\.)+)$".r
val origInit = readLine
val init = initialStateReg.findFirstMatchIn(origInit)
.map(m => m.group(1)).get
.zipWithIndex.flatMap {
case ('.', i) => None
case ('#', i) => Some(i)
}
.toSet
val rules = Iterator
.continually(readLine)
.takeWhile(_ != null)
.flatMap(parseRule)
.toList
val gens = List.range(1, LAST_GEN + 1, 1).scanLeft(0 -> init) {
case (gen, id) => id -> computeGeneration(gen._2, rules) }
val min = gens.map(_._2.min).min - 2
val max = gens.map(_._2.max).max + 2
gens.foreach(printGeneration(min, max))