This repository has been archived by the owner on Dec 4, 2023. It is now read-only.
generated from kotlin-hands-on/advent-of-code-kotlin-template
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathDay11.kt
76 lines (68 loc) · 2.66 KB
/
Day11.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
64
65
66
67
68
69
70
71
72
73
74
75
76
fun main() {
fun List<String>.parseMonkeys() = map { section ->
val lines = section.split('\n')
val index = lines[0].split(' ')[1].dropLast(1).toInt()
val items = lines[1].trim().split(' ').drop(2).map { it.removeSuffix(",").toLong() }.toMutableList()
val condition: (Long) -> Long = lines[2].trim().split(' ').takeLast(2).let { (op, value) ->
if (op == "*") ({
it * if (value == "old") it else value.toLong()
}) else ({
it + if (value == "old") it else value.toLong()
})
}
val divisibleBy = lines[3].trim().split(' ').last().toLong()
val testTrue = lines[4].trim().split(' ').last().toInt()
val testFalse = lines[5].trim().split(' ').last().toInt()
Monkey(index, items, condition, divisibleBy, testTrue, testFalse)
}.sortedBy(Monkey::index)
fun List<Monkey>.calculateInspections(rounds: Int, worryReducer: (Long) -> Long): LongArray {
val inspections = LongArray(size) { 0 }
repeat(rounds) {
forEach { monkey ->
monkey.items.forEach { item ->
val new = worryReducer(monkey.operation(item))
if (new % monkey.divisibleBy == 0L) {
this[monkey.testTrue].items.add(new)
} else {
this[monkey.testFalse].items.add(new)
}
}
inspections[monkey.index] = inspections[monkey.index] + monkey.items.size
monkey.items.clear()
}
}
return inspections
}
fun part1(input: List<String>): Long {
return input.parseMonkeys()
.calculateInspections(rounds = 20) { it / 3 }
.sortedDescending()
.take(2)
.product()
}
fun part2(input: List<String>): Long {
val monkeys = input.parseMonkeys()
val lcm = monkeys.map(Monkey::divisibleBy).lcm()
return input.parseMonkeys()
.calculateInspections(rounds = 10_000) { it % lcm }
.sortedDescending()
.take(2)
.product()
}
// test if implementation meets criteria from the description, like:
val testInput = readLinesSplitedbyEmptyLine("Day11_test")
check(part1(testInput) == 10605L)
val input = readLinesSplitedbyEmptyLine("Day11")
println(part1(input))
// part 2
check(part2(testInput) == 2713310158)
println(part2(input))
}
private data class Monkey(
val index: Int,
val items: MutableList<Long>,
val operation: (Long) -> Long,
val divisibleBy: Long,
val testTrue: Int,
val testFalse: Int,
)