@@ -11,15 +11,20 @@ const BEAM: char = '|';
1111
1212pub struct Day07 ;
1313
14+ type Splits = u16 ;
15+ type Timelines = u16 ;
16+
1417impl Solution for Day07 {
1518 fn part_one ( & self , input : & str ) -> String {
1619 let ( splits, _) = self . run ( input) ;
1720
1821 splits. to_string ( )
1922 }
2023
21- fn part_two ( & self , _input : & str ) -> String {
22- String :: from ( "0" )
24+ fn part_two ( & self , input : & str ) -> String {
25+ let ( _, timelines) = self . run ( input) ;
26+
27+ timelines. to_string ( )
2328 }
2429}
2530
@@ -30,31 +35,33 @@ impl Day07 {
3035 Grid :: from ( without_redundant_lines. as_str ( ) )
3136 }
3237
33- fn run ( & self , input : & str ) -> ( u16 , u16 ) {
38+ fn run ( & self , input : & str ) -> ( Splits , Timelines ) {
3439 let grid = self . parse ( input) ;
3540 let rows_range = grid. rows_range ( ) ;
3641 let start = grid. get_first_position ( & START ) . unwrap ( ) ;
3742
3843 let splitters: HashSet < Point > = grid. get_all_positions ( & SPLITTER ) . into_iter ( ) . collect ( ) ;
3944
45+ let mut split_beams: Vec < Beam > = Vec :: new ( ) ;
4046 let mut finished_beams: Vec < Beam > = Vec :: new ( ) ;
41- let mut current_beams: VecDeque < Beam > = VecDeque :: from ( vec ! [ start. into( ) ] ) ;
42- let mut splits = 0u16 ;
47+ let mut current_beams: VecDeque < Beam > = VecDeque :: from ( vec ! [ Beam :: new( start) ] ) ;
4348
44- while let Some ( current_beam) = current_beams. pop_front ( ) {
45- if finished_beams
46- . iter ( )
47- . chain ( current_beams. iter ( ) )
48- . any ( |beam| beam . collides ( & current_beam ) )
49+ ' while_loop : while let Some ( current_beam) = current_beams. pop_front ( ) {
50+ for beam in split_beams
51+ . iter_mut ( )
52+ . chain ( current_beams. iter_mut ( ) )
53+ . chain ( finished_beams . iter_mut ( ) )
4954 {
50- continue ;
55+ if current_beam. collides ( beam) {
56+ * beam = beam. merge ( current_beam) ;
57+ continue ' while_loop;
58+ }
5159 }
5260
5361 let down = current_beam. down ( ) ;
5462
5563 if splitters. contains ( & down. current ( ) ) {
56- finished_beams. push ( current_beam) ;
57- splits += 1 ;
64+ split_beams. push ( current_beam) ;
5865
5966 for split in down. split ( ) {
6067 current_beams. push_back ( split) ;
@@ -68,10 +75,15 @@ impl Day07 {
6875 continue ;
6976 }
7077
71- current_beams. push_front ( down) ;
78+ current_beams. push_back ( down) ;
7279 }
7380
74- ( splits, 0 )
81+ (
82+ split_beams. len ( ) as Splits ,
83+ finished_beams
84+ . iter ( )
85+ . fold ( 0 , |acc, beam| acc + beam. timelines ) ,
86+ )
7587 }
7688}
7789
@@ -88,9 +100,17 @@ fn print(grid: &Grid<char>, beams: &[Beam]) {
88100#[ derive( Copy , Clone , Debug ) ]
89101struct Beam {
90102 line : Line ,
103+ timelines : u16 ,
91104}
92105
93106impl Beam {
107+ fn new ( point : Point ) -> Self {
108+ Self {
109+ line : Line :: new ( point, point) ,
110+ timelines : 1 ,
111+ }
112+ }
113+
94114 fn collides ( & self , other : & Self ) -> bool {
95115 let other = other. current ( ) ;
96116
@@ -103,6 +123,7 @@ impl Beam {
103123 fn down ( & self ) -> Self {
104124 Self {
105125 line : Line :: new ( self . line . start ( ) , self . line . end ( ) . south ( ) ) ,
126+ timelines : self . timelines ,
106127 }
107128 }
108129
@@ -111,22 +132,25 @@ impl Beam {
111132 }
112133
113134 fn split ( & self ) -> Vec < Beam > {
114- vec ! [ self . current( ) . west( ) . into( ) , self . current( ) . east( ) . into( ) ]
115- }
116- }
117-
118- impl From < Point > for Beam {
119- fn from ( value : Point ) -> Self {
120- Self {
121- line : Line :: new ( value, value) ,
122- }
135+ let west = self . current ( ) . west ( ) ;
136+ let east = self . current ( ) . east ( ) ;
137+
138+ vec ! [
139+ Self {
140+ line: Line :: new( west, west) ,
141+ timelines: self . timelines,
142+ } ,
143+ Self {
144+ line: Line :: new( east, east) ,
145+ timelines: self . timelines,
146+ } ,
147+ ]
123148 }
124- }
125149
126- impl From < ( Point , Point ) > for Beam {
127- fn from ( value : ( Point , Point ) ) -> Self {
150+ fn merge ( & self , other : Self ) -> Self {
128151 Self {
129- line : Line :: new ( value. 0 , value. 1 ) ,
152+ line : self . line ,
153+ timelines : self . timelines + other. timelines ,
130154 }
131155 }
132156}
@@ -181,28 +205,33 @@ mod tests {
181205 assert_eq ! ( "21" , Day07 . part_one( EXAMPLE ) ) ;
182206 }
183207
208+ #[ test]
209+ fn part_two_example_test ( ) {
210+ assert_eq ! ( "40" , Day07 . part_two( EXAMPLE ) ) ;
211+ }
212+
184213 #[ test]
185214 fn beam_collides ( ) {
186- let beam: Beam = ( Point :: new ( 3 , 0 ) , Point :: new ( 3 , 3 ) ) . into ( ) ;
187-
188- assert ! ( !beam. collides( & Beam :: from ( Point :: new( 3 , -1 ) ) ) ) ;
189- assert ! ( beam. collides( & Beam :: from ( Point :: new( 3 , 0 ) ) ) ) ;
190- assert ! ( beam. collides( & Beam :: from ( Point :: new( 3 , 1 ) ) ) ) ;
191- assert ! ( beam. collides( & Beam :: from ( Point :: new( 3 , 2 ) ) ) ) ;
192- assert ! ( beam. collides( & Beam :: from ( Point :: new( 3 , 3 ) ) ) ) ;
193- assert ! ( !beam. collides( & Beam :: from ( Point :: new( 3 , 4 ) ) ) ) ;
194-
195- assert ! ( !beam. collides( & Beam :: from ( Point :: new( 2 , 0 ) ) ) ) ;
196- assert ! ( !beam. collides( & Beam :: from ( Point :: new( 2 , 1 ) ) ) ) ;
197- assert ! ( !beam. collides( & Beam :: from ( Point :: new( 2 , 2 ) ) ) ) ;
198- assert ! ( !beam. collides( & Beam :: from ( Point :: new( 2 , 3 ) ) ) ) ;
199- assert ! ( !beam. collides( & Beam :: from ( Point :: new( 2 , 4 ) ) ) ) ;
200-
201- assert ! ( !beam. collides( & Beam :: from ( Point :: new( 4 , 0 ) ) ) ) ;
202- assert ! ( !beam. collides( & Beam :: from ( Point :: new( 4 , 1 ) ) ) ) ;
203- assert ! ( !beam. collides( & Beam :: from ( Point :: new( 4 , 2 ) ) ) ) ;
204- assert ! ( !beam. collides( & Beam :: from ( Point :: new( 4 , 3 ) ) ) ) ;
205- assert ! ( !beam. collides( & Beam :: from ( Point :: new( 4 , 4 ) ) ) ) ;
215+ let beam: Beam = Beam :: new ( Point :: new ( 3 , 0 ) ) . down ( ) . down ( ) . down ( ) ;
216+
217+ assert ! ( !beam. collides( & Beam :: new ( Point :: new( 3 , -1 ) ) ) ) ;
218+ assert ! ( beam. collides( & Beam :: new ( Point :: new( 3 , 0 ) ) ) ) ;
219+ assert ! ( beam. collides( & Beam :: new ( Point :: new( 3 , 1 ) ) ) ) ;
220+ assert ! ( beam. collides( & Beam :: new ( Point :: new( 3 , 2 ) ) ) ) ;
221+ assert ! ( beam. collides( & Beam :: new ( Point :: new( 3 , 3 ) ) ) ) ;
222+ assert ! ( !beam. collides( & Beam :: new ( Point :: new( 3 , 4 ) ) ) ) ;
223+
224+ assert ! ( !beam. collides( & Beam :: new ( Point :: new( 2 , 0 ) ) ) ) ;
225+ assert ! ( !beam. collides( & Beam :: new ( Point :: new( 2 , 1 ) ) ) ) ;
226+ assert ! ( !beam. collides( & Beam :: new ( Point :: new( 2 , 2 ) ) ) ) ;
227+ assert ! ( !beam. collides( & Beam :: new ( Point :: new( 2 , 3 ) ) ) ) ;
228+ assert ! ( !beam. collides( & Beam :: new ( Point :: new( 2 , 4 ) ) ) ) ;
229+
230+ assert ! ( !beam. collides( & Beam :: new ( Point :: new( 4 , 0 ) ) ) ) ;
231+ assert ! ( !beam. collides( & Beam :: new ( Point :: new( 4 , 1 ) ) ) ) ;
232+ assert ! ( !beam. collides( & Beam :: new ( Point :: new( 4 , 2 ) ) ) ) ;
233+ assert ! ( !beam. collides( & Beam :: new ( Point :: new( 4 , 3 ) ) ) ) ;
234+ assert ! ( !beam. collides( & Beam :: new ( Point :: new( 4 , 4 ) ) ) ) ;
206235 }
207236
208237 const EXAMPLE_FROM_REDDIT : & str = r#"..S..
@@ -235,6 +264,11 @@ mod tests {
235264 assert_eq ! ( "4" , Day07 . part_one( EXAMPLE_FROM_REDDIT2 ) ) ;
236265 }
237266
267+ #[ test]
268+ fn part_two_example_from_reddit2 ( ) {
269+ assert_eq ! ( "6" , Day07 . part_two( EXAMPLE_FROM_REDDIT2 ) ) ;
270+ }
271+
238272 const MY_EXAMPLE : & str = r#"..S..
239273.....
240274..^..
@@ -249,6 +283,11 @@ mod tests {
249283 assert_eq ! ( "3" , Day07 . part_one( MY_EXAMPLE ) ) ;
250284 }
251285
286+ #[ test]
287+ fn part_two_my_example ( ) {
288+ assert_eq ! ( "4" , Day07 . part_two( MY_EXAMPLE ) ) ;
289+ }
290+
252291 const MY_EXAMPLE2 : & str = r#"..S..
253292.....
254293..^..
@@ -264,4 +303,34 @@ mod tests {
264303 fn part_one_my_example2 ( ) {
265304 assert_eq ! ( "6" , Day07 . part_one( MY_EXAMPLE2 ) ) ;
266305 }
306+
307+ const MY_EXAMPLE3 : & str = r#"...S...
308+ .......
309+ ...^...
310+ .......
311+ ..^.^..
312+ .......
313+ .^...^.
314+ ......."# ;
315+
316+ #[ test]
317+ fn part_two_my_example3 ( ) {
318+ assert_eq ! ( "6" , Day07 . part_two( MY_EXAMPLE3 ) ) ;
319+ }
320+
321+ const MY_EXAMPLE3_EXTENDED : & str = r#"...S...
322+ .......
323+ ...^...
324+ .......
325+ ..^.^..
326+ .......
327+ .^...^.
328+ .......
329+ ...^...
330+ ......."# ;
331+
332+ #[ test]
333+ fn part_two_my_example3_extended ( ) {
334+ assert_eq ! ( "8" , Day07 . part_two( MY_EXAMPLE3_EXTENDED ) ) ;
335+ }
267336}
0 commit comments