diff --git a/samples/day11.txt b/samples/day11.txt new file mode 100644 index 0000000..986aad4 --- /dev/null +++ b/samples/day11.txt @@ -0,0 +1,10 @@ +...#...... +.......#.. +#......... +.......... +......#... +.#........ +.........# +.......... +.......#.. +#...#..... diff --git a/src/bin/day11.rs b/src/bin/day11.rs new file mode 100644 index 0000000..db30db3 --- /dev/null +++ b/src/bin/day11.rs @@ -0,0 +1,113 @@ +use std::collections::HashSet; + +use itertools::iproduct; + +use aoc_2023::*; + +type Output1 = u64; +type Output2 = Output1; + +struct Day11 { + galaxies: Vec<(i64, i64)>, + empty_ys: HashSet, + empty_xs: HashSet, +} +impl Solution for Day11 { + fn new>(pathname: P) -> Self { + let lines: Vec = file_to_lines(pathname); + let map = lines.iter().map(|l| l.chars().collect_vec()).collect_vec(); + + let galaxies = iproduct!((0..map.len()), (0..map[0].len())) + .filter_map(|(y, x)| { + (map[y][x] != '.').then(|| (y.try_into().unwrap(), x.try_into().unwrap())) + }) + .collect(); + + let empty_ys = map + .iter() + .enumerate() + .filter(|&(_, l)| l.iter().all(|&c| c == '.')) + .map(|(y, _)| y) + .collect(); + + let empty_xs = (0..map[0].len()) + .filter(|&x| (0..map[x].len()).all(|y| map[y][x] == '.')) + .collect(); + + Self { + galaxies, + empty_ys, + empty_xs, + } + } + + fn part_1(&mut self) -> Output1 { + (0..self.galaxies.len() - 1) + .map(|i| { + let (y0, x0) = self.galaxies[i]; + + (i + 1..self.galaxies.len()) + .map(|j| { + let (y1, x1) = self.galaxies[j]; + + let mut xd = x0.abs_diff(x1); + let mut yd = y0.abs_diff(y1); + + let (min_x, max_x) = if x0 <= x1 { (x0, x1) } else { (x1, x0) }; + for x in &self.empty_xs { + if (min_x as usize) < *x && *x < max_x as usize { + xd += 1; + } + } + + for y in &self.empty_ys { + if (y0 as usize) < *y && *y < (y1 as usize) { + yd += 1; + } + } + + xd + yd + }) + .sum::() + }) + .sum::() + } + + fn part_2(&mut self) -> Output2 { + (0..self.galaxies.len() - 1) + .map(|i| { + let (y0, x0) = self.galaxies[i]; + + (i + 1..self.galaxies.len()) + .map(|j| { + let (y1, x1) = self.galaxies[j]; + + let mut xd = x0.abs_diff(x1); + let mut yd = y0.abs_diff(y1); + + let (min_x, max_x) = if x0 <= x1 { (x0, x1) } else { (x1, x0) }; + for x in &self.empty_xs { + if (min_x as usize) < *x && *x < max_x as usize { + xd += 999999; + } + } + + for y in &self.empty_ys { + if (y0 as usize) < *y && *y < (y1 as usize) { + yd += 999999; + } + } + + xd + yd + }) + .sum::() + }) + .sum::() + } +} + +fn main() -> Result<()> { + Day11::main() +} + +test_sample!(day_11, Day11, 374, 82000210);