1
1
use crate :: data:: load;
2
- use std:: collections:: { HashMap , HashSet } ;
2
+ use std:: {
3
+ cmp,
4
+ collections:: { HashMap , HashSet } ,
5
+ } ;
3
6
use thiserror:: Error ;
4
7
5
8
#[ derive( Error , Debug , PartialEq , Eq ) ]
@@ -70,25 +73,30 @@ impl Beam {
70
73
fn new ( loc : Coord , dir : Direction ) -> Self {
71
74
Beam { loc, dir }
72
75
}
76
+ }
73
77
78
+ impl Beam {
74
79
fn move_up ( & self ) -> Self {
75
80
let mut b = * self ;
76
81
b. dir = Direction :: Up ;
77
82
b. loc . r -= 1 ;
78
83
b
79
84
}
85
+
80
86
fn move_down ( & self ) -> Self {
81
87
let mut b = * self ;
82
88
b. dir = Direction :: Down ;
83
89
b. loc . r += 1 ;
84
90
b
85
91
}
92
+
86
93
fn move_left ( & self ) -> Self {
87
94
let mut b = * self ;
88
95
b. dir = Direction :: Left ;
89
96
b. loc . c -= 1 ;
90
97
b
91
98
}
99
+
92
100
fn move_right ( & self ) -> Self {
93
101
let mut b = * self ;
94
102
b. dir = Direction :: Right ;
@@ -143,16 +151,43 @@ fn move_beam(beam: &Beam, grid: &HashMap<Coord, CaveObject>, beam_tracker: &mut
143
151
}
144
152
}
145
153
146
- pub fn puzzle_1 ( input : & str ) -> Result < usize , PuzzleErr > {
147
- let grid = parse_input ( input) ?;
154
+ fn count_energized_tiles ( starting_beam : Beam , grid : & HashMap < Coord , CaveObject > ) -> usize {
148
155
let mut energized_coords = HashSet :: new ( ) ;
149
- let beam = Beam :: new ( Coord { r : 0 , c : 0 } , Direction :: Right ) ;
150
- move_beam ( & beam, & grid, & mut energized_coords) ;
151
- Ok ( energized_coords
156
+ move_beam ( & starting_beam, grid, & mut energized_coords) ;
157
+ energized_coords
152
158
. iter ( )
153
159
. map ( |b| b. loc )
154
160
. collect :: < HashSet < _ > > ( )
155
- . len ( ) )
161
+ . len ( )
162
+ }
163
+
164
+ pub fn puzzle_1 ( input : & str ) -> Result < usize , PuzzleErr > {
165
+ let grid = parse_input ( input) ?;
166
+ let beam = Beam :: new ( Coord { r : 0 , c : 0 } , Direction :: Right ) ;
167
+ Ok ( count_energized_tiles ( beam, & grid) )
168
+ }
169
+
170
+ pub fn puzzle_2 ( input : & str ) -> Result < usize , PuzzleErr > {
171
+ let grid = parse_input ( input) ?;
172
+ let mut max = 0 ;
173
+ let height = grid. keys ( ) . map ( |c| c. r ) . max ( ) . unwrap ( ) ;
174
+ let width = grid. keys ( ) . map ( |c| c. c ) . max ( ) . unwrap ( ) ;
175
+
176
+ for r in 0 ..=height {
177
+ for ( c, dir) in [ ( 0 , Direction :: Right ) , ( width, Direction :: Left ) ] {
178
+ let beam = Beam :: new ( Coord { r, c } , dir) ;
179
+ max = cmp:: max ( max, count_energized_tiles ( beam, & grid) ) ;
180
+ }
181
+ }
182
+
183
+ for c in 0 ..=width {
184
+ for ( r, dir) in [ ( 0 , Direction :: Down ) , ( height, Direction :: Up ) ] {
185
+ let beam = Beam :: new ( Coord { r, c } , dir) ;
186
+ max = cmp:: max ( max, count_energized_tiles ( beam, & grid) ) ;
187
+ }
188
+ }
189
+
190
+ Ok ( max)
156
191
}
157
192
158
193
pub fn main ( data_dir : & str ) {
@@ -168,10 +203,10 @@ pub fn main(data_dir: &str) {
168
203
assert_eq ! ( answer_1, Ok ( 6921 ) ) ;
169
204
170
205
// Puzzle 2.
171
- // let answer_2 = puzzle_2(&data);
172
- // match answer_2 {
173
- // Ok(x) => println!(" Puzzle 2: {}", x),
174
- // Err(e) => panic!("No solution to puzzle 2: {}", e),
175
- // }
176
- // assert_eq!(answer_2, Ok(30449 ))
206
+ let answer_2 = puzzle_2 ( & data) ;
207
+ match answer_2 {
208
+ Ok ( x) => println ! ( " Puzzle 2: {}" , x) ,
209
+ Err ( e) => panic ! ( "No solution to puzzle 2: {}" , e) ,
210
+ }
211
+ assert_eq ! ( answer_2, Ok ( 7594 ) )
177
212
}
0 commit comments