@@ -4,17 +4,15 @@ use mygrid::{direction::ORTHOGONAL, grid::Grid, point::Point};
44
55advent_of_code:: solution!( 18 ) ; 
66
7- fn  parse_points ( input :  & str )  -> Vec < Point >  { 
8-     input
9-         . lines ( ) 
10-         . filter ( |line| !line. is_empty ( ) ) 
11-         . map ( |line| { 
12-             let  ( col,  line)  = line. split_once ( ',' ) . unwrap ( ) ; 
13-             Point :: new ( line. parse ( ) . unwrap ( ) ,  col. parse ( ) . unwrap ( ) ) 
14-         } ) 
15-         . collect ( ) 
7+ #[ inline]  
8+ fn  parse_points < ' a > ( input :  & ' a  str )  -> impl  Iterator < Item  = Point >  + ' a  { 
9+     input. lines ( ) . filter ( |line| !line. is_empty ( ) ) . map ( |line| { 
10+         let  ( col,  line)  = line. split_once ( ',' ) . unwrap ( ) ; 
11+         Point :: new ( line. parse ( ) . unwrap ( ) ,  col. parse ( ) . unwrap ( ) ) 
12+     } ) 
1613} 
1714
15+ #[ inline]  
1816fn  fill_min_dst_grid ( grid :  & Grid < char > ,  min_dst :  & mut  Grid < u32 > ,  start :  ( Point ,  u32 ) ,  end :  Point )  { 
1917    let  mut  q = VecDeque :: new ( ) ; 
2018    q. push_back ( start) ; 
@@ -41,7 +39,7 @@ fn fill_min_dst_grid(grid: &Grid<char>, min_dst: &mut Grid<u32>, start: (Point,
4139fn  find_shortest_path ( input :  & str ,  width :  usize ,  height :  usize ,  take :  usize )  -> Option < u32 >  { 
4240    let  mut  grid = Grid :: new ( width,  height,  '.' ) ; 
4341    let  points = parse_points ( input) ; 
44-     points. iter ( ) . take ( take) . for_each ( |& p| { 
42+     points. take ( take) . for_each ( |p| { 
4543        grid[ p]  = '#' ; 
4644    } ) ; 
4745
@@ -62,7 +60,7 @@ pub fn part_one(input: &str) -> Option<u32> {
6260// work in reverse, fill them all in and find the first point that makes it possible to reach the end 
6361fn  find_cutoff ( input :  & str ,  width :  usize ,  height :  usize ,  _initial_take :  usize )  -> Option < Point >  { 
6462    let  mut  grid = Grid :: new ( width,  height,  '.' ) ; 
65-     let  points = parse_points ( input) ; 
63+     let  points = parse_points ( input) . collect :: < Vec < _ > > ( ) ; 
6664
6765    points. iter ( ) . for_each ( |& p| { 
6866        grid[ p]  = '#' ; 
@@ -75,31 +73,30 @@ fn find_cutoff(input: &str, width: usize, height: usize, _initial_take: usize) -
7573
7674    fill_min_dst_grid ( & grid,  & mut  min_dst,  ( start,  0 ) ,  end) ; 
7775
78-     let  mut  idx = points. len ( ) ; 
79-     while  min_dst[ end]  == u32:: MAX  { 
80-         idx -= 1 ; 
81- 
82-         let  p = points[ idx] ; 
76+     points. iter ( ) . rev ( ) . find_map ( |& p| { 
8377        grid[ p]  = '.' ; 
8478
8579        let  min_neighbour_dst = ORTHOGONAL 
8680            . iter ( ) 
8781            . map ( |& dir| p + dir) 
8882            . filter ( |& p| grid. is_in_bounds ( p) ) 
89-             . filter ( |& p| grid[ p]  == '.' ) 
9083            . map ( |p| min_dst[ p] ) 
9184            . min ( ) 
9285            . unwrap_or ( u32:: MAX ) ; 
9386
9487        if  min_neighbour_dst == u32:: MAX  { 
95-             continue ; 
88+             return   None ; 
9689        } 
9790        let  dst = min_neighbour_dst + 1 ; 
9891
9992        fill_min_dst_grid ( & grid,  & mut  min_dst,  ( p,  dst) ,  end) ; 
100-     } 
10193
102-     Some ( points[ idx] ) 
94+         if  min_dst[ end]  != u32:: MAX  { 
95+             return  Some ( p) ; 
96+         } 
97+ 
98+         return  None ; 
99+     } ) 
103100} 
104101
105102pub  fn  part_two ( input :  & str )  -> Option < String >  { 
0 commit comments