Commit c75526b8 authored by Alexander Gehrke's avatar Alexander Gehrke
Browse files

[day16] solution

parent 1cbdecb2
class: 1-3 or 5-7
row: 6-11 or 33-44
seat: 13-40 or 45-50
your ticket:
7,1,14
nearby tickets:
7,3,47
40,4,50
55,2,20
38,6,12
class: 0-1 or 4-19
row: 0-5 or 8-19
seat: 0-13 or 16-19
your ticket:
11,12,13
nearby tickets:
3,9,18
15,1,5
5,14,9
package aoc2020
import aoc2020.lib._
def day16(input: List[String]): String =
val List(rulesIn, List(_, ownIn), _ :: nearbyIn) = input.split("").toList
val rules = parseRules(rulesIn)
val own = parseTicket(ownIn)
val nearby = nearbyIn.map(parseTicket)
val (errorRate, valid) = nearby.foldLeft((0, Vector[Vector[Int]]())){
case ((errors, valids), ticket) => findErrors(rules)(ticket) match {
case Nil => (errors, valids :+ ticket)
case err => (errors + err.sum, valids)
}}
val columns = findFields(rules)(valid)
val departureInfo = columns.filter(_._1.startsWith("departure")).view.mapValues(own(_)).toMap
val checksum = departureInfo.values.map(_.toLong).product
s"""Error rate: $errorRate\n
|Departure Columns: ${departureInfo.mkString("\n -", "\n -", "")}
|Departure Checksum: $checksum
""".stripMargin
type Rules = Map[String, Vector[Range]]
def parseRules(input: List[String]): Rules =
input.map {
case s"$name: $ranges" => name -> ranges.split(" or ").nn.map(parseRange).toVector
}.toMap
def parseRange(str: String): Range = str.splitOnce("-").map(_.toInt to _.toInt).get
def parseTicket(str: String): Vector[Int] = str.split(",").nn.map(_.toInt).toVector
def findErrors(rules: Rules)(ticket: Vector[Int]): Vector[Int] =
ticket.filter(num => !rules.values.flatten.exists(_ contains num))
def findFields(rules: Rules)(tickets: Vector[Vector[Int]]) =
val candidates = tickets.transpose.map(col => rules.filter((rule, ranges) =>
col.forall(c => ranges.exists(_ contains c))
).keys.toSet)
candidates.zipWithIndex.sortBy(_._1.size).foldLeft(Map[String, Int]()){
case (legend, (candidates, col)) => legend + ((candidates -- legend.keys).head -> col)
}
......@@ -17,6 +17,7 @@ package aoc2020
case 13 => input()(day13)
case 14 => input()(day14)
case 15 => input()(day15)
case 16 => input()(day16)
case _ => "No such day implemented"
}
if (sample.nonEmpty) println("SAMPLE VALUES!")
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment