@@ -79,7 +79,7 @@ object Day20 {
79
79
return pulseCount
80
80
}
81
81
82
- private fun multiplePushButton (times : Int ): Map <Boolean , Long > {
82
+ private fun highLowPulsesCounts (times : Int ): Map <Boolean , Long > {
83
83
val pulseCount = mutableMapOf (true to 0L , false to 0L )
84
84
85
85
for (i in 1 .. times)
@@ -88,9 +88,48 @@ object Day20 {
88
88
return pulseCount
89
89
}
90
90
91
- fun part1 () = println (multiplePushButton(1000 ).values.reduce { acc, i -> acc * i })
91
+ private fun pushesToGetRx (): Long {
92
+ val beforeRxName = modules.filter { it.value.outputs.contains(" rx" ) }.map { it.key }.single()
93
+ val beforeRxInputsCounts = modules.filter { it.value.outputs.contains(beforeRxName) }.mapValues { 0L }.toMutableMap()
94
+ var pushCount = 0L
95
+
96
+ while (beforeRxInputsCounts.any { it.value == 0L }) {
97
+ pushCount++
98
+
99
+ val queue = LinkedList <Triple <String , Boolean , String >>()
100
+
101
+ queue.add(Triple (" broadcaster" , false , " " ))
102
+
103
+ while (queue.isNotEmpty()) {
104
+ val (destination, pulse, from) = queue.removeFirst()
105
+ val module = modules[destination]
106
+
107
+ if (destination == beforeRxName && pulse) {
108
+ beforeRxInputsCounts[from] = pushCount
109
+ }
110
+
111
+ module?.send(pulse, from)?.forEach {
112
+ queue.add(Triple (it.key, it.value, destination))
113
+ }
114
+ }
115
+ }
116
+
117
+ return beforeRxInputsCounts.values.reduce { acc, i -> lcm(acc, i) }
118
+ }
119
+
120
+ private fun gcd (a : Long , b : Long ): Long = if (b == 0L ) a else gcd(b, a % b)
121
+
122
+ private fun lcm (a : Long , b : Long ): Long = a * b / gcd(a, b)
123
+
124
+ fun resetModules () = modules.forEach { it.value.reset() }
125
+
126
+ fun part1 () = println (highLowPulsesCounts(1000 ).values.reduce { acc, i -> acc * i })
127
+
128
+ fun part2 () = println (pushesToGetRx())
92
129
}
93
130
94
131
fun main () {
95
132
Day20 .part1()
133
+ Day20 .resetModules()
134
+ Day20 .part2()
96
135
}
0 commit comments