11use crate :: solutions:: Solution ;
22use crate :: utils:: grid:: Grid ;
3+ use crate :: utils:: point:: Point ;
4+ use itertools:: Itertools ;
5+
6+ const ROLL_OF_PAPER : char = '@' ;
37
48pub struct Day04 ;
59
610impl Solution for Day04 {
711 fn part_one ( & self , input : & str ) -> String {
8- const ROLL_OF_PAPER : char = '@' ;
912 let grid: Grid < char > = Grid :: from ( input) ;
1013
1114 grid. get_all_positions ( & ROLL_OF_PAPER )
@@ -21,8 +24,41 @@ impl Solution for Day04 {
2124 . to_string ( )
2225 }
2326
24- fn part_two ( & self , _input : & str ) -> String {
25- String :: from ( "0" )
27+ fn part_two ( & self , input : & str ) -> String {
28+ let mut grid: Grid < char > = Grid :: from ( input) ;
29+
30+ let mut removed_count: u32 = 0 ;
31+ for roll in grid. get_all_positions ( & ROLL_OF_PAPER ) {
32+ Self :: try_to_remove ( & mut grid, & roll, & mut removed_count) ;
33+ }
34+
35+ removed_count. to_string ( )
36+ }
37+ }
38+
39+ impl Day04 {
40+ fn try_to_remove ( grid : & mut Grid < char > , roll : & Point , removed_count : & mut u32 ) {
41+ if grid
42+ . get_for_point ( roll)
43+ . is_some_and ( |e| * e != ROLL_OF_PAPER )
44+ {
45+ return ;
46+ }
47+
48+ let adjacent = roll. adjacent_with_diagonal_vectors ( ) ;
49+ let adjacent_rolls = adjacent
50+ . iter ( )
51+ . filter ( |adj| grid. is_for_point ( & adj. position ( ) , ROLL_OF_PAPER ) )
52+ . collect_vec ( ) ;
53+
54+ if adjacent_rolls. len ( ) < 4 {
55+ grid. modify ( * roll, 'X' ) ;
56+ * removed_count += 1 ;
57+
58+ for adj_roll in adjacent_rolls {
59+ Self :: try_to_remove ( grid, & adj_roll. position ( ) , removed_count) ;
60+ }
61+ }
2662 }
2763}
2864
@@ -46,4 +82,9 @@ mod tests {
4682 fn part_one_example_test ( ) {
4783 assert_eq ! ( "13" , Day04 . part_one( EXAMPLE ) ) ;
4884 }
85+
86+ #[ test]
87+ fn part_two_example_test ( ) {
88+ assert_eq ! ( "43" , Day04 . part_two( EXAMPLE ) ) ;
89+ }
4990}
0 commit comments