@@ -4,17 +4,15 @@ use mygrid::{direction::ORTHOGONAL, grid::Grid, point::Point};
4
4
5
5
advent_of_code:: solution!( 18 ) ;
6
6
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
+ } )
16
13
}
17
14
15
+ #[ inline]
18
16
fn fill_min_dst_grid ( grid : & Grid < char > , min_dst : & mut Grid < u32 > , start : ( Point , u32 ) , end : Point ) {
19
17
let mut q = VecDeque :: new ( ) ;
20
18
q. push_back ( start) ;
@@ -41,7 +39,7 @@ fn fill_min_dst_grid(grid: &Grid<char>, min_dst: &mut Grid<u32>, start: (Point,
41
39
fn find_shortest_path ( input : & str , width : usize , height : usize , take : usize ) -> Option < u32 > {
42
40
let mut grid = Grid :: new ( width, height, '.' ) ;
43
41
let points = parse_points ( input) ;
44
- points. iter ( ) . take ( take) . for_each ( |& p| {
42
+ points. take ( take) . for_each ( |p| {
45
43
grid[ p] = '#' ;
46
44
} ) ;
47
45
@@ -62,7 +60,7 @@ pub fn part_one(input: &str) -> Option<u32> {
62
60
// work in reverse, fill them all in and find the first point that makes it possible to reach the end
63
61
fn find_cutoff ( input : & str , width : usize , height : usize , _initial_take : usize ) -> Option < Point > {
64
62
let mut grid = Grid :: new ( width, height, '.' ) ;
65
- let points = parse_points ( input) ;
63
+ let points = parse_points ( input) . collect :: < Vec < _ > > ( ) ;
66
64
67
65
points. iter ( ) . for_each ( |& p| {
68
66
grid[ p] = '#' ;
@@ -75,31 +73,30 @@ fn find_cutoff(input: &str, width: usize, height: usize, _initial_take: usize) -
75
73
76
74
fill_min_dst_grid ( & grid, & mut min_dst, ( start, 0 ) , end) ;
77
75
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| {
83
77
grid[ p] = '.' ;
84
78
85
79
let min_neighbour_dst = ORTHOGONAL
86
80
. iter ( )
87
81
. map ( |& dir| p + dir)
88
82
. filter ( |& p| grid. is_in_bounds ( p) )
89
- . filter ( |& p| grid[ p] == '.' )
90
83
. map ( |p| min_dst[ p] )
91
84
. min ( )
92
85
. unwrap_or ( u32:: MAX ) ;
93
86
94
87
if min_neighbour_dst == u32:: MAX {
95
- continue ;
88
+ return None ;
96
89
}
97
90
let dst = min_neighbour_dst + 1 ;
98
91
99
92
fill_min_dst_grid ( & grid, & mut min_dst, ( p, dst) , end) ;
100
- }
101
93
102
- Some ( points[ idx] )
94
+ if min_dst[ end] != u32:: MAX {
95
+ return Some ( p) ;
96
+ }
97
+
98
+ return None ;
99
+ } )
103
100
}
104
101
105
102
pub fn part_two ( input : & str ) -> Option < String > {
0 commit comments