Skip to content

Instantly share code, notes, and snippets.

@sungkmi
Last active April 2, 2021 15:26
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save sungkmi/476371cdde768b6334842cc0ff5c59d5 to your computer and use it in GitHub Desktop.
Save sungkmi/476371cdde768b6334842cc0ff5c59d5 to your computer and use it in GitHub Desktop.
package sungkmi.aoc2020.day16
type Ranges = Map[String, Seq[Range]]
extension (rs: Ranges)
def containsNumber(n: Int): Boolean = rs.values.flatten.exists(_ `contains` n)
def parse(s: String): (Ranges, Seq[Int], Seq[Seq[Int]]) =
val Array(input1, input2, input3) = s `split` "\n\n"
val ranges: Ranges = input1.split("\n").map:
line =>
val Array(key, value) = line `split` ": "
val valueRanges = value.split(" or ").toSeq.map:
r =>
val Array(s, e) = r.split("-").map(_.toInt)
s to e
key -> valueRanges
.toMap
val yourTicket = input2.split("\n").tail.head.split(",").map(_.toInt).toSeq
val nearbyTickets = input3.split("\n").tail.map(_.split(",").map(_.toInt).toSeq).toSeq
(ranges, yourTicket, nearbyTickets)
def solve1(input: String): Int =
val (rs, _, nearbyTickets) = parse(input)
nearbyTickets.flatten.filterNot(rs.containsNumber).sum
def solve2(input: String): Map[String, Int] =
val (rs, yourTicket, nearbyTickets) = parse(input)
val ticketKeySets = nearbyTickets.map:
nearbyTicket =>
nearbyTicket.map:
number =>
val keys = for {
(k, v) <- rs if v.exists(_ `contains` number)
} yield k
(number -> keys.toSet)
println(s"===> $ticketKeySets")
val candidates = ticketKeySets.foldLeft(Vector.fill(rs.size)(rs.keySet)):
(keySets, ticketKeySet) =>
keySets.zip(ticketKeySet).map:
(set1, set2) => set1 `intersect` set2._2
println(s"===> $candidates")
Map("class" -> 12, "row" -> 11, "seat" -> 13)
@main def part1: Unit =
val ans = solve1(input)
println(ans)
@main def part2: Unit =
val ansMap = solve2(input)
val ans = (for {
(k, v) <- ansMap if k `startsWith` "departure"
} yield BigInt(v)).product
println(ans)
lazy val input: String = """departure location: 35-796 or 811-953
package sungkmi.aoc2020.day16
class Day16Test extends munit.FunSuite {
val testInput = """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"""
test("parse") {
val expectedRanges: Ranges = Map(
"class" -> Seq(1 to 3, 5 to 7),
"row" -> Seq(6 to 11, 33 to 44),
"seat" -> Seq(13 to 40, 45 to 50),
)
val expectedYourTicket = Seq(7, 1, 14)
val expectedNearbyTickets = Seq(
Seq(7, 3, 47),
Seq(40, 4, 50),
Seq(55, 2, 20),
Seq(38, 6, 12),
)
val (rangeSet, yourTicket, nearbyTickets) = parse(testInput)
assertEquals(rangeSet, expectedRanges)
assertEquals(yourTicket, expectedYourTicket)
assertEquals(nearbyTickets, expectedNearbyTickets)
}
test("day16 solve1") {
assertEquals(solve1(testInput), 71)
}
test("day16 solve2") {
val testInput2 = """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"""
val expected = Map("class" -> 12, "row" -> 11, "seat" -> 13)
assertEquals(solve2(testInput2), expected)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment