@@ -28,6 +28,7 @@ struct Cheat {
2828struct Node {
2929 pos : Vec2 < i32 > ,
3030 picos : i32 ,
31+ cost : i32 ,
3132 cheat : Option < Cheat > ,
3233}
3334
@@ -70,13 +71,13 @@ impl Racetrack {
7071
7172 /// Finds paths through the racetrack, ordered ascendingly by total picoseconds.
7273 fn find_paths ( & self , start : Vec2 < i32 > , end : Vec2 < i32 > , cheat_policy : CheatPolicy , condition : impl Fn ( Node ) -> bool ) -> Vec < Node > {
73- // Your run-of-the-mill Dijkstra implementation
74+ // Your run-of-the-mill A* ( Dijkstra + heuristic) implementation
7475
7576 let mut queue = BinaryHeap :: new ( ) ;
7677 let mut visited = HashSet :: new ( ) ;
7778 let mut paths = Vec :: new ( ) ;
7879
79- queue. push ( Node { pos : start, picos : 0 , cheat : None } ) ;
80+ queue. push ( Node { pos : start, picos : 0 , cost : 0 , cheat : None } ) ;
8081 visited. insert ( ( start, None ) ) ;
8182
8283 while let Some ( node) = queue. pop ( ) {
@@ -110,7 +111,11 @@ impl Racetrack {
110111
111112 if !visited. contains ( & ( neigh, new_cheat) ) && ( !is_wall || can_cheat) {
112113 visited. insert ( ( neigh, new_cheat) ) ;
113- queue. push ( Node { pos : neigh, picos : node. picos + 1 , cheat : new_cheat } ) ;
114+
115+ let new_picos = node. picos + 1 ;
116+ let new_dist_to_end = ( neigh. x . abs_diff ( end. x ) + neigh. y . abs_diff ( end. y ) ) as i32 ;
117+ let new_cost = new_picos + new_dist_to_end;
118+ queue. push ( Node { pos : neigh, picos : new_picos, cost : new_cost, cheat : new_cheat } ) ;
114119 }
115120 }
116121 }
@@ -149,9 +154,5 @@ fn main() {
149154 let cheat_paths = track. find_paths ( start, end, CheatPolicy :: Allowed , |n| n. picos < base_picos) ;
150155 let part1 = cheat_paths. len ( ) ;
151156
152- for p in cheat_paths. iter ( ) . map ( |n| ( base_picos - n. picos , n. cheat ) ) {
153- println ! ( "{p:?}" ) ;
154- }
155-
156157 println ! ( "Part 1: {part1}" ) ;
157158}
0 commit comments