-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathDay07HandyHaversacks.kt
63 lines (51 loc) · 1.86 KB
/
Day07HandyHaversacks.kt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
package adventofcode.year2020
import adventofcode.Puzzle
import adventofcode.PuzzleInput
class Day07HandyHaversacks(customInput: PuzzleInput? = null) : Puzzle(customInput) {
private val bagRules by lazy {
input.lines().map { rule ->
val (color) = BAG_RULE_REGEX.find(rule)!!.destructured
val contents =
BAG_CONTENTS_REGEX
.findAll(rule)
.map { it.destructured }
.associate { (amount, color) -> color to amount.toInt() }
Bag(color, contents)
}
}
override fun partOne() =
bagRules
.count { it.contains(bagRules, "shiny gold") }
override fun partTwo() =
bagRules
.get("shiny gold")
.size(bagRules)
.minus(1)
companion object {
val BAG_RULE_REGEX = """(\w+ \w+) bags contain (.*)""".toRegex()
val BAG_CONTENTS_REGEX = """(\d+) (\w+ \w+) bags?(, )?""".toRegex()
private data class Bag(
val color: String,
val contents: Map<String, Int>,
) {
fun contains(
bagRules: List<Bag>,
searchPattern: String,
): Boolean {
if (contents.isEmpty()) return false
if (contents.containsKey(searchPattern)) return true
return contents
.map { bagRules.get(it.key).contains(bagRules, searchPattern) }
.contains(true)
}
fun size(bagRules: List<Bag>): Int {
if (contents.isEmpty()) return 1
return contents
.map { bagRules.get(it.key).size(bagRules) * it.value }
.sum()
.plus(1)
}
}
private fun List<Bag>.get(color: String) = this.first { it.color == color }
}
}