1
1
use crate :: util:: hash:: * ;
2
+ use crate :: util:: heap:: * ;
2
3
use std:: array:: from_fn;
3
- use std:: cmp:: Ordering ;
4
- use std:: collections:: BinaryHeap ;
5
4
use std:: hash:: * ;
6
5
7
6
const A : usize = 0 ;
@@ -88,26 +87,6 @@ impl Burrow {
88
87
}
89
88
}
90
89
91
- #[ derive( Copy , Clone , PartialEq , Eq ) ]
92
- struct State {
93
- burrow : Burrow ,
94
- energy : usize ,
95
- }
96
-
97
- impl PartialOrd for State {
98
- #[ inline]
99
- fn partial_cmp ( & self , other : & Self ) -> Option < Ordering > {
100
- Some ( self . cmp ( other) )
101
- }
102
- }
103
-
104
- impl Ord for State {
105
- #[ inline]
106
- fn cmp ( & self , other : & Self ) -> Ordering {
107
- other. energy . cmp ( & self . energy )
108
- }
109
- }
110
-
111
90
pub fn parse ( input : & str ) -> Vec < Vec < usize > > {
112
91
input
113
92
. lines ( )
@@ -136,13 +115,12 @@ pub fn part2(input: &[Vec<usize>]) -> usize {
136
115
}
137
116
138
117
fn organize ( burrow : Burrow ) -> usize {
139
- let mut todo = BinaryHeap :: with_capacity ( 20_000 ) ;
118
+ let mut todo = MinHeap :: with_capacity ( 20_000 ) ;
140
119
let mut seen = FastMap :: with_capacity ( 20_000 ) ;
141
120
142
- todo. push ( State { burrow , energy : best_possible ( & burrow) } ) ;
121
+ todo. push ( best_possible ( & burrow) , burrow ) ;
143
122
144
- while let Some ( state) = todo. pop ( ) {
145
- let State { mut burrow, energy } = state;
123
+ while let Some ( ( energy, mut burrow) ) = todo. pop ( ) {
146
124
let open: [ bool ; 4 ] = from_fn ( |i| burrow. rooms [ i] . open ( i) ) ;
147
125
148
126
let mut changed = false ;
@@ -164,7 +142,7 @@ fn organize(burrow: Burrow) -> usize {
164
142
// Moving back to home burrow does not change cost
165
143
let min = seen. get ( & burrow) . unwrap_or ( & usize:: MAX ) ;
166
144
if energy < * min {
167
- todo. push ( State { burrow , energy } ) ;
145
+ todo. push ( energy , burrow ) ;
168
146
seen. insert ( burrow, energy) ;
169
147
}
170
148
} else {
@@ -173,8 +151,8 @@ fn organize(burrow: Burrow) -> usize {
173
151
let offset = 2 + 2 * i;
174
152
let forward = ( offset + 1 ) ..11 ;
175
153
let reverse = ( 0 ..offset) . rev ( ) ;
176
- expand ( & mut todo, & mut seen, & state , i, forward) ;
177
- expand ( & mut todo, & mut seen, & state , i, reverse) ;
154
+ expand ( & mut todo, & mut seen, burrow , energy , i, forward) ;
155
+ expand ( & mut todo, & mut seen, burrow , energy , i, reverse) ;
178
156
}
179
157
}
180
158
}
@@ -240,13 +218,13 @@ fn condense(burrow: &mut Burrow, kind: usize, iter: impl Iterator<Item = usize>)
240
218
}
241
219
242
220
fn expand (
243
- todo : & mut BinaryHeap < State > ,
221
+ todo : & mut MinHeap < usize , Burrow > ,
244
222
seen : & mut FastMap < Burrow , usize > ,
245
- state : & State ,
223
+ mut burrow : Burrow ,
224
+ energy : usize ,
246
225
room_index : usize ,
247
226
iter : impl Iterator < Item = usize > ,
248
227
) {
249
- let State { mut burrow, energy } = state;
250
228
let kind = burrow. rooms [ room_index] . pop ( ) ;
251
229
252
230
for hallway_index in iter {
@@ -290,7 +268,7 @@ fn expand(
290
268
let min = seen. get ( & next) . unwrap_or ( & usize:: MAX ) ;
291
269
292
270
if next_energy < * min {
293
- todo. push ( State { burrow : next , energy : next_energy } ) ;
271
+ todo. push ( next_energy , next ) ;
294
272
seen. insert ( next, next_energy) ;
295
273
}
296
274
}
0 commit comments