diff --git a/2023/src/bin/day11.rs b/2023/src/bin/day11.rs index 49e84ad..5e3221b 100644 --- a/2023/src/bin/day11.rs +++ b/2023/src/bin/day11.rs @@ -13,32 +13,32 @@ fn parse_input(raw: &str) -> Parsed { .enumerate() .flat_map(|(x, l)| l.bytes().enumerate().filter_map(move |(y, b)| (b == b'#').then_some((x, y)))) .collect_vec(); - let &xmax = galaxies.iter().map(|(x, _)| x).max().unwrap(); - let &ymax = galaxies.iter().map(|(_, y)| y).max().unwrap(); - let mut xs = vec![true; xmax + 1]; - let mut ys = vec![true; ymax + 1]; + let max = raw.lines().next().unwrap().len(); + let mut xs = vec![true; max]; + let mut ys = vec![true; max]; for &(x, y) in galaxies.iter() { xs[x] = false; ys[y] = false; } - ( - xs.into_iter().enumerate().filter_map(|(x, b)| b.then_some(x)).collect(), - ys.into_iter().enumerate().filter_map(|(y, b)| b.then_some(y)).collect(), - galaxies, - ) + (sliding_count(xs), sliding_count(ys), galaxies) } -fn distance(x1: &I, x2: &I, empty: &[I]) -> I { - let smaller_x = x1.min(x2); - let bigger_x = x1.max(x2); - empty.iter().filter(|x| (smaller_x..=bigger_x).contains(x)).count() * FACTOR + bigger_x - smaller_x +fn sliding_count(bools: Vec) -> Vec { + bools + .into_iter() + .scan(0, |prev, b| { + *prev += b as I; + Some(*prev) + }) + .collect() } -fn solve((empty_x, empty_y, galaxies): &Parsed) -> usize { +fn solve((x_offset, y_offset, galaxies): &Parsed) -> usize { galaxies .iter() + .map(|&(x, y)| (x + x_offset[x] * FACTOR, y + y_offset[y] * FACTOR)) .tuple_combinations() - .map(|((x1, y1), (x2, y2))| distance::(x1, x2, empty_x) + distance::(y1, y2, empty_y)) + .map(|((x1, y1), (x2, y2))| x1.abs_diff(x2) + y1.abs_diff(y2)) .sum() } @@ -67,5 +67,5 @@ boilerplate! { }, bench1 == 9623138, bench2 == 726820169514, - bench_parse: |(a, b, c): &Parsed| (a.len(), b.len(), c.len()) => (9, 11, 432), + bench_parse: |(a, b, c): &Parsed| (a.len(), b.len(), c.len()) => (140, 140, 432), }