@@ -11,36 +11,26 @@ class Day11 {
11
11
12
12
fun part1 (input : String ): Long {
13
13
val monkeys = parseInput(input).associateBy(Monkey ::id)
14
-
15
- for (round in 1 .. 20 ) {
16
- monkeys.forEach { (_, monkey) ->
17
- monkey.items.forEach { item ->
18
- item.worryLevel = monkey.inspectItem(item) / 3
19
- val newMonkeyId = monkey.chooseTargetMonkey(item.worryLevel)
20
-
21
- monkeys[newMonkeyId]?.items?.add(item)
22
- }
23
- monkey.items.clear()
24
- }
25
- }
26
-
27
- val (m1, m2) = monkeys.values
28
- .sortedByDescending(Monkey ::totalItemsInspected)
29
- .take(2 )
30
-
31
- return m1.totalItemsInspected * m2.totalItemsInspected
14
+ return startGame(monkeys, 20 , 3 )
32
15
}
33
16
34
17
fun part2 (input : String ): Long {
35
18
val monkeys = parseInput(input).associateBy(Monkey ::id)
19
+ return startGame(monkeys, 10_000 , 1 )
20
+ }
36
21
37
- for (round in 1 .. 10_000 ) {
22
+ private fun startGame (monkeys : Map <Int , Monkey >, rounds : Int , reliefModifier : Int ): Long {
23
+ val commonDenominator = monkeys.values
24
+ .map(Monkey ::divisibleValue)
25
+ .reduce { acc, v -> acc * v }
26
+
27
+ for (round in 1 .. rounds) {
38
28
monkeys.forEach { (_, monkey) ->
39
29
monkey.items.forEach { item ->
40
- item.worryLevel = monkey.inspectItem(item)
41
- val newMonkeyId = monkey.chooseTargetMonkey(item.worryLevel )
30
+ val newWorryLevel = ( monkey.inspectItem(item) / reliefModifier) % commonDenominator
31
+ val newMonkeyId = monkey.chooseTargetMonkey(newWorryLevel )
42
32
43
- monkeys[newMonkeyId]?.items?.add(item )
33
+ monkeys[newMonkeyId]?.items?.add(newWorryLevel )
44
34
}
45
35
monkey.items.clear()
46
36
}
@@ -50,27 +40,22 @@ class Day11 {
50
40
.sortedByDescending(Monkey ::totalItemsInspected)
51
41
.take(2 )
52
42
53
- // After 10000 rounds, the two most active monkeys inspected
54
- // items 52166 and 52013 times.
55
- // Multiplying these together, the level of monkey business in this situation
56
- // is now 2713310158.
57
43
return m1.totalItemsInspected * m2.totalItemsInspected
58
44
}
59
45
60
- data class Item (val id : Int , var worryLevel : Long )
61
-
62
46
data class Monkey (
63
47
val id : Int ,
64
48
val inspectOperation : MonkeyOperation ,
65
49
val chooseTargetMonkey : MonkeyTest ,
66
- val items : LinkedList <Item >
50
+ val items : MutableList <Long >,
51
+ val divisibleValue : Int
67
52
) {
68
53
var totalItemsInspected = 0L
69
54
private set
70
55
71
- fun inspectItem (item : Item ): Long {
56
+ fun inspectItem (itemWorryLevel : Long ): Long {
72
57
totalItemsInspected++
73
- return inspectOperation(item.worryLevel )
58
+ return inspectOperation(itemWorryLevel )
74
59
}
75
60
}
76
61
@@ -82,27 +67,27 @@ class Day11 {
82
67
* If true: throw to monkey 2
83
68
* If false: throw to monkey 3
84
69
*/
85
- fun parseInput (input : String ): LinkedList <Monkey > {
70
+ private fun parseInput (input : String ): LinkedList <Monkey > {
86
71
val monkeys = LinkedList <Monkey >()
87
- val itemIndexGenerator = generateSequence(0 ) { it + 1 }.iterator()
88
72
89
73
input.split(" \n\n " ).mapIndexed { i, value ->
90
74
val lines = value.split(" \n " ).map(String ::trimIndent)
91
75
92
- val items = parseItems(lines[1 ], itemIndexGenerator )
76
+ val items = parseItems(lines[1 ])
93
77
val operation = parseOperation(lines[2 ])
94
78
val test = parseTest(lines[3 ], lines[4 ], lines[5 ])
79
+ val divisibleValue = lines[3 ].split(" " ).last().toInt()
95
80
96
- Monkey (i, operation, test, LinkedList < Item >( items) )
81
+ Monkey (i, operation, test, items.toMutableList(), divisibleValue )
97
82
}.forEach(monkeys::add)
98
83
99
84
return monkeys
100
85
}
101
86
102
87
// Parse: Starting items: 79, 98
103
- private fun parseItems (input : String , itemIndexGenerator : Iterator < Int > ): List <Item > {
88
+ private fun parseItems (input : String ): List <Long > {
104
89
return MATCH_NUMBERS .findAll(input).map {
105
- Item (itemIndexGenerator.next(), it.value.toLong() )
90
+ it.value.toLong()
106
91
}.toList()
107
92
}
108
93
0 commit comments