Skip to content

Commit d1fcebd

Browse files
committed
5am fuled map
1 parent 45754a4 commit d1fcebd

File tree

1 file changed

+68
-12
lines changed

1 file changed

+68
-12
lines changed

src/day24.rs

Lines changed: 68 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -272,7 +272,7 @@ pub fn part2(s: &str) -> &'static str {
272272
part2_inner(s)
273273
}
274274

275-
const ZSTART: u16 = 26 * 26 * 26;
275+
const ZSTART: u16 = 0;
276276

277277
#[inline(always)]
278278
pub fn part2_inner(s: &[u8]) -> &'static str {
@@ -287,6 +287,7 @@ pub fn part2_inner(s: &[u8]) -> &'static str {
287287
struct Gate {
288288
out_1: u16,
289289
out_2: u16,
290+
id: u16,
290291
state: State,
291292
}
292293

@@ -301,14 +302,20 @@ pub fn part2_inner(s: &[u8]) -> &'static str {
301302
}
302303
}
303304

304-
let mut gates = [Gate {
305-
out_1: 0,
306-
out_2: 0,
307-
state: State::Or,
308-
}; 26 * 26 * 26 + 46];
309-
310305
let mut inputs = [(0u16, 0u16); 45];
311306

307+
let mut gates_map = heapless::FnvIndexMap::<u16, u16, 512>::new();
308+
309+
let mut gates = heapless::Vec::<Gate, 512>::from_slice(
310+
&[Gate {
311+
out_1: 0,
312+
out_2: 0,
313+
id: 0,
314+
state: State::Or,
315+
}; 46],
316+
)
317+
.unwrap();
318+
312319
let mut i = CSTART;
313320
unsafe {
314321
while i < s.len() {
@@ -322,11 +329,25 @@ pub fn part2_inner(s: &[u8]) -> &'static str {
322329
let this = if *s.get_unchecked(i + len + 12) == b'z' {
323330
(s.get_unchecked(i + len + 13) - b'0') as u16 * 10
324331
+ (s.get_unchecked(i + len + 14) - b'0') as u16
325-
+ 26 * 26 * 26
326332
} else {
327-
(s.get_unchecked(i + len + 12) - b'a') as u16 * 26 * 26
333+
let this = (s.get_unchecked(i + len + 12) - b'a') as u16 * 26 * 26
328334
+ (s.get_unchecked(i + len + 13) - b'a') as u16 * 26
329-
+ (s.get_unchecked(i + len + 14) - b'a') as u16
335+
+ (s.get_unchecked(i + len + 14) - b'a') as u16;
336+
337+
match gates_map.entry(this) {
338+
heapless::Entry::Occupied(occupied_entry) => *occupied_entry.get(),
339+
heapless::Entry::Vacant(vacant_entry) => {
340+
let i = gates.len() as u16;
341+
gates.push_unchecked(Gate {
342+
out_1: 0,
343+
out_2: 0,
344+
id: *vacant_entry.key(),
345+
state: State::Or,
346+
});
347+
vacant_entry.insert(i).unwrap_unchecked();
348+
i
349+
}
350+
}
330351
};
331352

332353
if *s.get_unchecked(i) == b'x' || *s.get_unchecked(i) == b'y' {
@@ -355,6 +376,34 @@ pub fn part2_inner(s: &[u8]) -> &'static str {
355376
let from2 = (s.get_unchecked(i + len + 5) - b'a') as u16 * 26 * 26
356377
+ (s.get_unchecked(i + len + 6) - b'a') as u16 * 26
357378
+ (s.get_unchecked(i + len + 7) - b'a') as u16;
379+
let from1 = match gates_map.entry(from1) {
380+
heapless::Entry::Occupied(occupied_entry) => *occupied_entry.get(),
381+
heapless::Entry::Vacant(vacant_entry) => {
382+
let i = gates.len() as u16;
383+
gates.push_unchecked(Gate {
384+
out_1: 0,
385+
out_2: 0,
386+
id: *vacant_entry.key(),
387+
state: State::Or,
388+
});
389+
vacant_entry.insert(i).unwrap_unchecked();
390+
i
391+
}
392+
};
393+
let from2 = match gates_map.entry(from2) {
394+
heapless::Entry::Occupied(occupied_entry) => *occupied_entry.get(),
395+
heapless::Entry::Vacant(vacant_entry) => {
396+
let i = gates.len() as u16;
397+
gates.push_unchecked(Gate {
398+
out_1: 0,
399+
out_2: 0,
400+
id: *vacant_entry.key(),
401+
state: State::Or,
402+
});
403+
vacant_entry.insert(i).unwrap_unchecked();
404+
i
405+
}
406+
};
358407

359408
gates.get_unchecked_mut(from1 as usize).add_out(this);
360409
gates.get_unchecked_mut(from2 as usize).add_out(this);
@@ -438,15 +487,22 @@ pub fn part2_inner(s: &[u8]) -> &'static str {
438487

439488
debug_assert_eq!(carry, ZSTART + 45);
440489

490+
for i in to_swap.iter_mut() {
491+
if *i < 46 {
492+
*i = 26 * 26 * 26 + *i;
493+
} else {
494+
*i = gates.get_unchecked(*i as usize).id;
495+
}
496+
}
441497
to_swap.sort_unstable();
442498
debug_assert_eq!(to_swap.len(), 8);
443499

444500
static mut OUTPUT: [u8; 8 * 4 - 1] = [b','; 8 * 4 - 1];
445501
let mut j = 0;
446502
while j < 8 {
447503
let w = *to_swap.get_unchecked(j);
448-
if w >= ZSTART {
449-
let w = w - ZSTART;
504+
if w >= (26 * 26 * 26) {
505+
let w = w - (26 * 26 * 26);
450506
OUTPUT[j * 4] = b'z';
451507
OUTPUT[j * 4 + 1] = (w / 10) as u8 + b'0';
452508
OUTPUT[j * 4 + 2] = (w % 10) as u8 + b'0';

0 commit comments

Comments
 (0)