Skip to content

Commit 90b33f4

Browse files
committed
2022/Day 10
1 parent b6c03d1 commit 90b33f4

File tree

5 files changed

+135
-0
lines changed

5 files changed

+135
-0
lines changed

README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,10 @@
4646
🎄 ---- Day 10: Cathode-Ray Tube ---
4747
🌟 Part 1: 12980 (12.51ms)
4848
🌟 Part 2: BRJLFULP (8.1us)
49+
50+
🎄 ---- Day 11: Monkey in the Middle ---
51+
🌟 Part 1: 76728 (30.8ms)
52+
🌟 Part 2: 21553910156 (100.1ms)
4953
```
5054

5155
## Visualizations

src/main/kotlin/me/grison/aoc/Strings.kt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package me.grison.aoc
22

3+
import java.math.BigInteger
34
import java.util.*
45

56
/** Returns the occurrences of `c`. */
@@ -80,6 +81,9 @@ fun String.allPositiveInts(): List<Int> = this.allInts(false)
8081
fun String.allLongs(includeNegative: Boolean = true): List<Long> =
8182
(if (includeNegative) "(-?\\d+)" else "(\\d+)").regex().findAll(this).map { it.value.toLong() }.toList()
8283

84+
fun String.allBigIntegers(includeNegative: Boolean = true): List<BigInteger> =
85+
(if (includeNegative) "(-?\\d+)" else "(\\d+)").regex().findAll(this).map { it.value.toBigInteger() }.toList()
86+
8387
fun String.firstInt(includeNegative: Boolean = true) = allInts(includeNegative).first()
8488
fun String.lastInt(includeNegative: Boolean = true) = allInts(includeNegative).last()
8589

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
package me.grison.aoc.y2022
2+
3+
import me.grison.aoc.*
4+
import java.math.BigInteger.ONE
5+
6+
class Monkey(
7+
var id: Int,
8+
var items: MutableList<Long>,
9+
var operation: (Long) -> Long,
10+
var divisible: Long,
11+
var destinations: Pair<Int, Int>
12+
)
13+
14+
class Day11 : Day(11, 2022) {
15+
override fun title() = "Monkey in the Middle"
16+
17+
override fun partOne() = solve(20, parseMonkeys()) { level -> level / 3L }
18+
19+
override fun partTwo() = parseMonkeys().let { monkeys ->
20+
val lcm = lcm(monkeys)
21+
solve(10_000, monkeys) { level -> level % lcm }
22+
}
23+
24+
private fun parseMonkeys(): List<Monkey> {
25+
val monkeys = mutableListOf<Monkey>()
26+
27+
inputGroups.forEach { monkey ->
28+
val (id, items, operation, divisible, ok, nok) = monkey.lines()
29+
val after = operation.after(": ").words()
30+
val (op, operand) = p(after[3], after[4])
31+
monkeys.add(
32+
Monkey(
33+
id.firstInt(),
34+
items.allLongs().toMutableList(),
35+
{ i ->
36+
when (operand.isDigits()) {
37+
false -> if (op == "+") i + i else i * i
38+
true -> if (op == "+") i + operand.toLong() else i * operand.toLong()
39+
}
40+
},
41+
divisible.allLongs().first(),
42+
p(ok.firstInt(), nok.firstInt())
43+
)
44+
)
45+
}
46+
47+
return monkeys
48+
}
49+
50+
private fun lcm(monkeys: List<Monkey>) =
51+
monkeys.map { it.divisible.toBigInteger() }.fold(ONE) { acc, i -> (acc * i) / acc.gcd(i) }.toLong()
52+
53+
private fun solve(rounds: Int, monkeys: List<Monkey>, newLevel: (Long) -> Long): Long {
54+
val monkeyBusiness = mutableList(monkeys.size, 0L)
55+
repeat(rounds) {
56+
monkeys.forEach { monkey ->
57+
monkey.items.forEach { item ->
58+
monkeyBusiness[monkey.id] += 1L
59+
val level = newLevel(monkey.operation(item))
60+
val destination =
61+
if (level % monkey.divisible == 0L) monkey.destinations.first
62+
else monkey.destinations.second
63+
monkeys[destination].items.add(level)
64+
}
65+
monkey.items.clear()
66+
}
67+
}
68+
69+
return monkeyBusiness.sorted().takeLast(2).product()
70+
}
71+
}

src/main/resources/2022/11.txt

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
Monkey 0:
2+
Starting items: 61
3+
Operation: new = old * 11
4+
Test: divisible by 5
5+
If true: throw to monkey 7
6+
If false: throw to monkey 4
7+
8+
Monkey 1:
9+
Starting items: 76, 92, 53, 93, 79, 86, 81
10+
Operation: new = old + 4
11+
Test: divisible by 2
12+
If true: throw to monkey 2
13+
If false: throw to monkey 6
14+
15+
Monkey 2:
16+
Starting items: 91, 99
17+
Operation: new = old * 19
18+
Test: divisible by 13
19+
If true: throw to monkey 5
20+
If false: throw to monkey 0
21+
22+
Monkey 3:
23+
Starting items: 58, 67, 66
24+
Operation: new = old * old
25+
Test: divisible by 7
26+
If true: throw to monkey 6
27+
If false: throw to monkey 1
28+
29+
Monkey 4:
30+
Starting items: 94, 54, 62, 73
31+
Operation: new = old + 1
32+
Test: divisible by 19
33+
If true: throw to monkey 3
34+
If false: throw to monkey 7
35+
36+
Monkey 5:
37+
Starting items: 59, 95, 51, 58, 58
38+
Operation: new = old + 3
39+
Test: divisible by 11
40+
If true: throw to monkey 0
41+
If false: throw to monkey 4
42+
43+
Monkey 6:
44+
Starting items: 87, 69, 92, 56, 91, 93, 88, 73
45+
Operation: new = old + 8
46+
Test: divisible by 3
47+
If true: throw to monkey 5
48+
If false: throw to monkey 2
49+
50+
Monkey 7:
51+
Starting items: 71, 57, 86, 67, 96, 95
52+
Operation: new = old + 7
53+
Test: divisible by 17
54+
If true: throw to monkey 3
55+
If false: throw to monkey 1

src/test/kotlin/me/grison/aoc/y2022/AllDaysTest.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ class AllDaysTest {
2121
Answer({ Day08() }, 1763, 671160),
2222
Answer({ Day09() }, 6026, 2273),
2323
Answer({ Day10() }, 12980, "BRJLFULP"),
24+
Answer({ Day11() }, 76728, 21553910156),
2425
).map {
2526
val day = it.inst.invoke()
2627
DynamicTest.dynamicTest("Day ${day.year}/${day.dayNumber} - Part 1 - expecting ${it.part1}") {

0 commit comments

Comments
 (0)