@@ -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