Skip to content

Commit fa6fc44

Browse files
committed
So will this be faster?
1 parent 2fb10fe commit fa6fc44

File tree

1 file changed

+95
-49
lines changed

1 file changed

+95
-49
lines changed

src/day20.rs

Lines changed: 95 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,24 @@ impl Dir {
4747
Dir::W => i.wrapping_sub(2),
4848
}
4949
}
50+
51+
fn select_crosline(&self, i: usize) -> u8 {
52+
(match self {
53+
Dir::N => i / SIZE1,
54+
Dir::E => i % SIZE1,
55+
Dir::S => i / SIZE1,
56+
Dir::W => i % SIZE1,
57+
}) as u8
58+
}
59+
60+
fn select_inline(&self, i: usize) -> u8 {
61+
(match self {
62+
Dir::N => i % SIZE1,
63+
Dir::E => i / SIZE1,
64+
Dir::S => i % SIZE1,
65+
Dir::W => i / SIZE1,
66+
}) as u8
67+
}
5068
}
5169

5270
#[aoc(day20, part1)]
@@ -121,82 +139,110 @@ pub fn part2(s: &str) -> u64 {
121139
}
122140
}
123141

142+
#[derive(Debug)]
143+
struct Line {
144+
start_ns: u16,
145+
line_start: u8,
146+
lien_offset: u8,
147+
}
148+
149+
const QUAD_SIZE: usize = 8;
150+
const QUADS_SIZE: usize = SIZE.div_ceil(QUAD_SIZE);
151+
const QUADS_NEEDED: usize = 20usize.div_ceil(QUAD_SIZE);
152+
124153
// #[target_feature(enable = "avx2,bmi1,bmi2,cmpxchg16b,lzcnt,movbe,popcnt")]
125154
fn inner_part2(s: &[u8]) -> u64 {
126155
let start = memchr::memchr(b'S', s).unwrap();
127156

128-
let mut ns_map = [0u16; SIZE1 * SIZE];
157+
let mut lines = [const { heapless::Vec::<Line, 512>::new() }; 4];
158+
let mut quads =
159+
[const { [const { heapless::Vec::<usize, 8>::new() }; QUADS_SIZE * QUADS_SIZE] }; 4];
129160

130161
let mut ns = 1;
131162

132-
let mut d = if s[start - 1] == b'.' {
163+
let mut i = start;
164+
let mut d = if s[i - 1] == b'.' {
133165
Dir::W
134-
} else if s[start + 1] == b'.' {
166+
} else if s[i + 1] == b'.' {
135167
Dir::E
136-
} else if s[start - SIZE1] == b'.' {
168+
} else if s[i - SIZE1] == b'.' {
137169
Dir::N
138170
} else {
139171
Dir::S
140172
};
141173

142-
let mut cy = start as i32 / SIZE1 as i32;
143-
let mut cx = start as i32 % SIZE1 as i32;
144-
145-
let idx = |x, y| (y * SIZE1 as i32 + x) as usize;
174+
lines[d as usize]
175+
.push(Line {
176+
start_ns: 0,
177+
line_start: d.select_crosline(i),
178+
lien_offset: d.select_inline(i),
179+
})
180+
.unwrap();
146181

147182
let mut sum = 0;
148-
while s[idx(cx, cy)] != b'E' {
149-
ns_map[idx(cx, cy)] = ns;
150183

151-
let next = d.step(idx(cx, cy));
152-
if s[next] == b'#' {
153-
for side in d.sides() {
154-
let side_i = side.step(idx(cx, cy));
155-
if s[side_i] != b'#' {
156-
d = side;
184+
let mut prev_qx = usize::MAX;
185+
let mut prev_qy = usize::MAX;
186+
while s[i] != b'E' {
187+
let qx = (i % SIZE1) / QUAD_SIZE;
188+
let qy = (i / SIZE1) / QUAD_SIZE;
189+
190+
for qx in
191+
qx.saturating_sub(QUADS_NEEDED)..qx.saturating_add(QUADS_NEEDED + 1).min(QUADS_SIZE)
192+
{
193+
for qy in
194+
qy.saturating_sub(QUADS_NEEDED)..qy.saturating_add(QUADS_NEEDED + 1).min(QUADS_SIZE)
195+
{
196+
for line_i in &quads[0][qy * QUADS_SIZE + qx] {
197+
sum += 1;
198+
}
199+
for line_i in &quads[1][qy * QUADS_SIZE + qx] {
200+
sum += 1;
201+
}
202+
for line_i in &quads[2][qy * QUADS_SIZE + qx] {
203+
sum += 1;
204+
}
205+
for line_i in &quads[3][qy * QUADS_SIZE + qx] {
206+
sum += 1;
157207
}
158208
}
159209
}
160-
match d {
161-
Dir::N => cy -= 1,
162-
Dir::E => cx += 1,
163-
Dir::S => cy += 1,
164-
Dir::W => cx -= 1,
165-
}
166-
ns += 1;
167210

168-
for y in (cy - 20).max(1)..(cy + 21).min(SIZE as i32 - 1) {
169-
for x in
170-
(-20 + (y - cy).abs() + cx).max(1)..(21 - (y - cy).abs() + cx).min(SIZE as i32 - 1)
171-
{
172-
let dist = (y - cy).abs() + (x - cx).abs();
173-
if dist <= 1 {
174-
continue;
175-
}
211+
if prev_qy != qy || prev_qx != qx {
212+
quads[d as usize][qy * QUADS_SIZE + qx]
213+
.push(lines[d as usize].len() - 1)
214+
.unwrap();
215+
}
216+
prev_qy = qy;
217+
prev_qx = qx;
176218

177-
let side_i = idx(x, y);
178-
if ns_map[side_i] != 0 {
179-
let diff = ns - ns_map[side_i];
180-
if diff >= MIN_CHEAT + dist as u16 {
181-
sum += 1;
182-
}
219+
let next = d.step(i);
220+
if s[next] == b'#' {
221+
for side in d.sides() {
222+
let side_i = side.step(i);
223+
if s[side_i] != b'#' {
224+
d = side;
183225
}
184226
}
227+
228+
lines[d as usize]
229+
.push(Line {
230+
start_ns: ns,
231+
line_start: d.select_crosline(i),
232+
lien_offset: d.select_inline(i),
233+
})
234+
.unwrap();
235+
quads[d as usize][qy * QUADS_SIZE + qx]
236+
.push(lines[d as usize].len() - 1)
237+
.unwrap();
238+
239+
i = d.step(i);
240+
} else {
241+
i = next;
185242
}
243+
ns += 1;
186244
}
187245

188-
// for y in 0..SIZE {
189-
// for x in 0..SIZE.min(40) {
190-
// if ns_map[y * SIZE1 + x] != 0 {
191-
// print!("{:^4} ", ns_map[y * SIZE1 + x]);
192-
// } else {
193-
// print!(" . ");
194-
// }
195-
// }
196-
// println!("");
197-
// }
198-
// println!("");
199-
200246
sum
201247
}
202248

0 commit comments

Comments
 (0)