Day 3
This commit is contained in:
parent
f1a35a8ab6
commit
d07dd395e1
2 changed files with 74 additions and 1 deletions
72
aoc/src/main/scala/aoc/y2018/Day03.scala
Normal file
72
aoc/src/main/scala/aoc/y2018/Day03.scala
Normal file
|
@ -0,0 +1,72 @@
|
||||||
|
package aoc.y2018
|
||||||
|
|
||||||
|
import aoc.Day
|
||||||
|
|
||||||
|
object Day03 extends Day {
|
||||||
|
|
||||||
|
import fastparse._, SingleLineWhitespace._
|
||||||
|
|
||||||
|
case class Claim(id: Int, pos: (Int, Int), size: (Int, Int))
|
||||||
|
|
||||||
|
def numParser[_: P]: P[Int] = P(CharIn("0-9").rep(1).!).map(_.toInt)
|
||||||
|
def idParser[_: P]: P[Int] = P("#" ~ numParser)
|
||||||
|
def coordParser[_: P]: P[(Int, Int)] = P(numParser ~ "," ~ numParser)
|
||||||
|
def dimensParser[_: P]: P[(Int, Int)] = P(numParser ~ "x" ~ numParser)
|
||||||
|
def claimParser[_: P]: P[Claim] = P(idParser ~ "@" ~ coordParser ~ ":" ~ dimensParser).map {
|
||||||
|
case (id, coords, dimens) => Claim(id, coords, dimens)
|
||||||
|
}
|
||||||
|
def claimsParser[_: P]: P[List[Claim]] = P(claimParser.rep(1, "\n"./)).map(_.toList)
|
||||||
|
|
||||||
|
def getClaims(input: String): List[Claim] = {
|
||||||
|
val Parsed.Success(claims, _) = parse(input, claimsParser(_))
|
||||||
|
claims
|
||||||
|
}
|
||||||
|
|
||||||
|
def insideRange(c: (Int, Int), p: (Int, Int), s: (Int, Int)): Boolean = {
|
||||||
|
(c, p, s) match {
|
||||||
|
case ((cx, cy), (px, py), (sw, sh)) =>
|
||||||
|
cx >= px &&
|
||||||
|
cx < px + sw &&
|
||||||
|
cy >= py &&
|
||||||
|
cy < py + sh
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def mapSection[A](l: List[List[A]], p: (Int, Int), s: (Int, Int), f: A => A): List[List[A]] = {
|
||||||
|
val coordinated = l.zipWithIndex.map { case (n, i) => n.zipWithIndex.map { case (e, y) => (e, y, i) } }
|
||||||
|
val mapped = coordinated.map(_.map { case (e, y, x) => if(insideRange((x, y), p, s)) f(e) else e })
|
||||||
|
mapped
|
||||||
|
}
|
||||||
|
|
||||||
|
def maxSize(c: List[Claim]): (Int, Int) = {
|
||||||
|
(c.map {
|
||||||
|
case Claim(_, (x, _), (w, _)) => x + w
|
||||||
|
}.max, c.map {
|
||||||
|
case Claim(_, (_, y), (_, h)) => y + h
|
||||||
|
}.max)
|
||||||
|
}
|
||||||
|
|
||||||
|
override def part1(input: String): String = {
|
||||||
|
val claims = getClaims(input)
|
||||||
|
val (highestW, highestH) = maxSize(claims)
|
||||||
|
val starting: List[List[Int]] = List.fill(highestW)(List.fill(highestH)(0))
|
||||||
|
val finished = claims.foldLeft(starting)((acc, cc) => {
|
||||||
|
mapSection(acc, cc.pos, cc.size, (i: Int) => i + 1)
|
||||||
|
})
|
||||||
|
finished.flatten.count(_ > 1).toString
|
||||||
|
}
|
||||||
|
|
||||||
|
override def part2(input: String): String = {
|
||||||
|
val claims = getClaims(input)
|
||||||
|
val (highestW, highestH) = maxSize(claims)
|
||||||
|
val starting: List[List[List[Int]]] = List.fill(highestW)(List.fill(highestH)(List()))
|
||||||
|
val finished = claims.foldLeft(starting)((acc, cc) => {
|
||||||
|
mapSection(acc, cc.pos, cc.size, (e: List[Int]) => cc.id :: e)
|
||||||
|
})
|
||||||
|
val all = finished.flatten
|
||||||
|
val oneInhabitant = all.filter(_.size == 1).map(_.head).toSet
|
||||||
|
val solitary = oneInhabitant.filter(i => all.filter(_.contains(i)).forall(_.size == 1))
|
||||||
|
solitary.head.toString
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -4,7 +4,8 @@ package object y2018 extends Year {
|
||||||
|
|
||||||
override def days: Map[String, Day] = Map(
|
override def days: Map[String, Day] = Map(
|
||||||
"1" -> Day01,
|
"1" -> Day01,
|
||||||
"2" -> Day02
|
"2" -> Day02,
|
||||||
|
"3" -> Day03,
|
||||||
)
|
)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue