@@ -6,25 +6,46 @@ pub fn part_one(input: &str) -> Option<u64> {
6
6
let mut program = Program :: from_input ( input) ;
7
7
let mut pulse_count = PulseCount :: new ( ) ;
8
8
9
+ let mut add_to_pulse_count = |pulse_packet : & PulsePacket | pulse_count. add ( pulse_packet. pulse ) ;
10
+
9
11
for _ in 0 ..1000 {
10
- program. run ( & mut pulse_count ) ;
12
+ program. run ( & mut add_to_pulse_count ) ;
11
13
}
12
14
13
15
Some ( pulse_count. high * pulse_count. low )
14
16
}
15
17
16
- pub fn part_two ( input : & str ) -> Option < u32 > {
17
- None
18
+ pub fn part_two ( input : & str ) -> Option < u64 > {
19
+ let mut program = Program :: from_input ( input) ;
20
+
21
+ // Due to the puzzle input shape we know the rx module has a single conjunction input
22
+ let receiver_module = program. module_inputs . get ( "rx" ) . unwrap ( ) [ 0 ] ;
23
+
24
+ let mut runtimes = HashMap :: new ( ) ;
25
+
26
+ for index in 0 ..2_u64 . pow ( 12 ) {
27
+ program. run ( & mut |pulse_packet| {
28
+ if pulse_packet. to == receiver_module && pulse_packet. pulse == Pulse :: High {
29
+ runtimes
30
+ . entry ( pulse_packet. from . to_owned ( ) )
31
+ . or_insert ( index + 1 ) ;
32
+ }
33
+ } )
34
+ }
35
+
36
+ Some ( runtimes. values ( ) . product :: < u64 > ( ) )
18
37
}
19
38
20
39
struct Program < ' a > {
21
40
modules : HashMap < & ' a str , Module < ' a > > ,
41
+ module_inputs : HashMap < & ' a str , Vec < & ' a str > > ,
22
42
}
23
43
24
44
impl Program < ' _ > {
25
45
fn from_input ( input : & str ) -> Program {
26
46
let mut module_outputs = Vec :: new ( ) ;
27
47
let mut modules = HashMap :: new ( ) ;
48
+ let mut module_inputs: HashMap < & str , Vec < & str > > = HashMap :: new ( ) ;
28
49
29
50
for line in input. lines ( ) {
30
51
let module = Module :: from_line ( line) ;
@@ -38,17 +59,25 @@ impl Program<'_> {
38
59
if let Some ( module) = modules. get_mut ( output_module) {
39
60
module. add_input ( module_name) ;
40
61
}
62
+
63
+ module_inputs
64
+ . entry ( output_module)
65
+ . or_default ( )
66
+ . push ( module_name) ;
41
67
}
42
68
}
43
69
44
- Program { modules }
70
+ Program {
71
+ modules,
72
+ module_inputs,
73
+ }
45
74
}
46
75
47
- fn run ( & mut self , pulse_count : & mut PulseCount ) {
76
+ fn run ( & mut self , on_pulse_packet : & mut impl FnMut ( & PulsePacket ) ) {
48
77
let mut pulse_packets = VecDeque :: from ( [ PulsePacket :: start ( ) ] ) ;
49
78
50
79
while let Some ( pulse_packet) = pulse_packets. pop_front ( ) {
51
- pulse_count . add ( pulse_packet. pulse ) ;
80
+ on_pulse_packet ( & pulse_packet) ;
52
81
53
82
if let Some ( module) = self . modules . get_mut ( pulse_packet. to ) {
54
83
if let Some ( pulse) = module. process ( pulse_packet) {
@@ -165,7 +194,7 @@ impl<'a> Logic<'a> {
165
194
}
166
195
}
167
196
168
- #[ derive( PartialEq , Copy , Clone ) ]
197
+ #[ derive( Debug , PartialEq , Copy , Clone ) ]
169
198
enum Pulse {
170
199
High ,
171
200
Low ,
@@ -198,7 +227,7 @@ struct PulsePacket<'a> {
198
227
impl < ' a > PulsePacket < ' a > {
199
228
fn start ( ) -> PulsePacket < ' a > {
200
229
PulsePacket {
201
- from : "" ,
230
+ from : "button " ,
202
231
to : "broadcaster" ,
203
232
pulse : Pulse :: Low ,
204
233
}
@@ -224,12 +253,4 @@ mod tests {
224
253
) ) ;
225
254
assert_eq ! ( result, Some ( 11687500 ) ) ;
226
255
}
227
-
228
- #[ test]
229
- fn test_part_two ( ) {
230
- let result = part_two ( & advent_of_code:: template:: read_file_part (
231
- "examples" , DAY , 3 ,
232
- ) ) ;
233
- assert_eq ! ( result, None ) ;
234
- }
235
256
}
0 commit comments