mirror of
https://github.com/bertptrs/adventofcode.git
synced 2025-12-25 21:00:31 +01:00
Flatten DP buffers
Going from 2d to 1d arrays improves cache locality and vectorization, resulting in a roughly 40% speedup for part 2.
This commit is contained in:
@@ -15,33 +15,32 @@ fn number_ways(line: &[u8], groups: &[u8]) -> u64 {
|
||||
return 0;
|
||||
};
|
||||
|
||||
let mut next = vec![vec![0; max_group as usize + 1]; groups.len() + 1];
|
||||
let group_stride = max_group as usize + 1;
|
||||
|
||||
let mut next = vec![0; (groups.len() + 1) * group_stride];
|
||||
let mut cur = next.clone();
|
||||
cur[0][0] = 1;
|
||||
cur[0] = 1;
|
||||
|
||||
for &c in line {
|
||||
for entry in &mut next {
|
||||
entry.fill(0);
|
||||
}
|
||||
next.fill(0);
|
||||
|
||||
for group_pos in 0..=groups.len() {
|
||||
for (group_pos, positions) in cur.chunks_exact(group_stride).enumerate() {
|
||||
let group = *groups.get(group_pos).unwrap_or(&0);
|
||||
for cur_group in 0..=max_group {
|
||||
let ways = cur[group_pos][cur_group as usize];
|
||||
for (cur_group, &ways) in positions.iter().enumerate() {
|
||||
if ways == 0 {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Either defective or maybe defective
|
||||
if c != b'.' && cur_group < group {
|
||||
next[group_pos][cur_group as usize + 1] += ways;
|
||||
if c != b'.' && cur_group < usize::from(group) {
|
||||
next[group_pos * group_stride + cur_group as usize + 1] += ways;
|
||||
}
|
||||
|
||||
if c != b'#' {
|
||||
if cur_group == 0 {
|
||||
next[group_pos][0] += ways;
|
||||
} else if group == cur_group {
|
||||
next[group_pos + 1][0] += ways;
|
||||
next[group_pos * group_stride] += ways;
|
||||
} else if usize::from(group) == cur_group {
|
||||
next[(group_pos + 1) * group_stride] += ways;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -50,7 +49,8 @@ fn number_ways(line: &[u8], groups: &[u8]) -> u64 {
|
||||
mem::swap(&mut cur, &mut next);
|
||||
}
|
||||
|
||||
cur[groups.len()][0] + cur[groups.len() - 1][groups[groups.len() - 1] as usize]
|
||||
cur[groups.len() * group_stride]
|
||||
+ cur[(groups.len() - 1) * group_stride + groups[groups.len() - 1] as usize]
|
||||
}
|
||||
|
||||
fn parse_lines(i: &[u8]) -> IResult<&[u8], Vec<(&[u8], Vec<u8>)>> {
|
||||
|
||||
Reference in New Issue
Block a user