Add day 12
This commit is contained in:
parent
506e288f61
commit
c60ed493d7
55
Day12.scala
Normal file
55
Day12.scala
Normal file
|
@ -0,0 +1,55 @@
|
|||
package aoc.day12
|
||||
|
||||
import aoc._
|
||||
import scala.collection.mutable
|
||||
|
||||
case class Record(input: String, groups: List[Int]):
|
||||
lazy val possibleFills = loop(0, groups)
|
||||
|
||||
def unfold(times: Int) =
|
||||
Record((1 to times).map(_ => input).mkString("?"), (1 to times).flatMap(_ => groups).toList)
|
||||
|
||||
private inline def canEmpty(pos: Char) = pos == '.' || pos == '?'
|
||||
private inline def canFill(pos: Char) = pos == '#' || pos == '?'
|
||||
|
||||
private val memo = mutable.Map.empty[(Int, Int), Long]
|
||||
private def loop(from: Int, groups: List[Int]): Long =
|
||||
if from == input.length() then (if groups.isEmpty then 1 else 0)
|
||||
else
|
||||
memo.getOrElseUpdate(
|
||||
(from, groups.length), {
|
||||
// don't fill this group
|
||||
val noFill = if canEmpty(input(from)) then loop(from + 1, groups) else 0
|
||||
// fill this group
|
||||
val doFill = groups match
|
||||
case head :: next if from + head <= input.length =>
|
||||
val slice = input.slice(from, from + head)
|
||||
if slice.forall(canFill(_)) then
|
||||
if from + head == input.length() then loop(from + head, next)
|
||||
else if canEmpty(input(from + head)) then loop(from + head + 1, next)
|
||||
else 0
|
||||
else 0
|
||||
case _ => 0
|
||||
noFill + doFill
|
||||
}
|
||||
)
|
||||
|
||||
object Parser extends CommonParser:
|
||||
val groups = repsep(num, ",")
|
||||
val record = """[?#.]+""".r ~ groups ^^ { case (input ~ groups) => Record(input, groups) }
|
||||
|
||||
def apply(s: String) = parse(record, s).get
|
||||
|
||||
val records = lines.map(Parser(_)).toSeq
|
||||
|
||||
def part1 =
|
||||
val result = records.map(_.possibleFills).sum
|
||||
println(result)
|
||||
|
||||
def part2 =
|
||||
val result = records.map(_.unfold(5).possibleFills).sum
|
||||
println(result)
|
||||
|
||||
@main def Day12(part: Int) = part match
|
||||
case 1 => part1
|
||||
case 2 => part2
|
1000
inputs/day12.input
Normal file
1000
inputs/day12.input
Normal file
File diff suppressed because it is too large
Load diff
Loading…
Reference in a new issue