From a3130543df0b63daec16505cac806361711190a1 Mon Sep 17 00:00:00 2001 From: Andrej Orsula Date: Mon, 11 Dec 2023 07:45:02 +0100 Subject: [PATCH] aoc2023/day11: Add solution Signed-off-by: Andrej Orsula --- README.md | 3 + aoc2023/input/2023/day11.txt | 140 +++++++++++++++++++++++++++++++++ aoc2023/src/day11.rs | 145 +++++++++++++++++++++++++++++++++++ aoc2023/src/lib.rs | 1 + 4 files changed, 289 insertions(+) create mode 100644 aoc2023/input/2023/day11.txt create mode 100644 aoc2023/src/day11.rs diff --git a/README.md b/README.md index 70be6fa..9339ebd 100644 --- a/README.md +++ b/README.md @@ -29,6 +29,7 @@ My solutions to [Advent of Code](https://adventofcode.com) puzzles. | 8 | [Haunted Wasteland](https://adventofcode.com/2023/day/8) | [`day8.rs`](aoc2023/src/day8.rs) | | 9 | [Mirage Maintenance](https://adventofcode.com/2023/day/9) | [`day9.rs`](aoc2023/src/day9.rs) | | 10 | [Pipe Maze](https://adventofcode.com/2023/day/10) | [`day10.rs`](aoc2023/src/day10.rs) | +| 11 | [Cosmic Expansion](https://adventofcode.com/2023/day/11) | [`day11.rs`](aoc2023/src/day11.rs) | @@ -44,6 +45,7 @@ My solutions to [Advent of Code](https://adventofcode.com) puzzles. | 109.8 µs | 314.2 µs | | 88.05 µs | 38.84 µs | | 126.5 µs | 147.0 µs | +| 6.720 ms | 1.116 ms | @@ -59,6 +61,7 @@ My solutions to [Advent of Code](https://adventofcode.com) puzzles. | 82.85 µs | 703.8 µs | | 80.19 µs | 45.75 µs | | 134.1 µs | 196.6 µs | +| 7.331 ms | 1.136 ms | diff --git a/aoc2023/input/2023/day11.txt b/aoc2023/input/2023/day11.txt new file mode 100644 index 0000000..5550d0e --- /dev/null +++ b/aoc2023/input/2023/day11.txt @@ -0,0 +1,140 @@ +.#...........#.........................................................................#...............#...........#........................ +.......................#.................................................................................................................... +...............................#...........#.................#.............................#.............................................#.. +......#............................................#........................................................................................ +......................................................................#.....#.....................#......................................... +.................#.......#.......................................#................#.....#.....................#............................. +.........................................#.................#................................................................................ +................................#.............................................................#..........#.................................. +#.......................................................................#..............................................#.................#.. +..........#....................................#......................................#............................................#........ +................#....................................#........#............................................................................. +......#........................................................................#............................................................ +......................#..............#..............................................................#..........#.....#...................... +..................................................#.......................#..................................................#..........#... +............................#............................................................................................................... +........#................................................................................................................................... +..................#.......................#................................................................#................................ +.............................................................#........#..................................................................... +..............................#.......#......................................#.............#........................#....................... +.#............................................................................................................#...........................#. +...................................................................................................#....................#................... +....................#......................#.............#.....#..................................................................#......... +.................................................................................................................#.......................... +............................................................................................................................................ +....................................................................#.....................#................................................. +.................................#..............................................#..............#............#.............#................. +...........................#............................................#...........................................#....................... +......................#.........................#........................................................................................... +.......................................#....................................#...................................#........................... +.....#..........#.........................................#...............................................................................#. +#..........#......................#...................................................#.......#.....#....................................... +.........................#.................................................................................................................. +....................#..............................#.............#.........................................#.......#........#............... +...........................................#........................................................................................#....... +...........................................................#....................#........................................................... +..........#....................................................................................................#............................ +...............#................................#..........................#..............................................................#. +..#.................................#.................................................................#.......................#............. +.....................#......#...............#........................#................................................#..................... +..............................................................................................#....................................#........ +................................#.......#................................................................................................... +..........#................................................#...................#.....#..............#..........#..........#................. +.........................#.................................................................................................................. +..................#...............................#...........................................................................#............. +.........................................................................#............................................#..................... +........#.....#..............................................................................#.........#..................................#. +.#...............................#......#............#.............................................................................#........ +....................................................................................#.............#...............#........#................ +...........................#................................................................................................................ +......................#..................................#..............#................................#.............#................#... +...............................................................#..............#............................................................. +..................................#........................................................#........#....................................... +......#.................................#.......#....................#...............................................................#...... +.................#............#..............................................................................#.............................# +............................................................................................................................................ +..#.....................#.............................................................................#..................................... +.......................................................................................#..............................#..................... +...............................................................................#.............#.............................................. +....................#.....................#...............................................................#................................. +..........#........................#............#...................#.............................................#...............#......... +............................#.............................#..........................#...................................................... +...........................................................................................#................................................ +.................................................................#.................................#.........................#........#..... +.................#........................................................#..................................#.............................. +......................................#......................#.............................................................................. +.............#...........#...............................................................................#..........#....................... +.................................#...........#...........................................................................#..............#... +.......#............................................#.....#....................#..............#.....#....................................... +...................#...........................................#................................................#........................... +........................................................................................#................................................... +...#....................#.....#............#.........................................................................................#...... +...............#.............................................................#..................#........#................#................. +.........#.....................................#............................................................................................ +................................................................................................................................#........... +.....................#.............#.........................................................................#.............................. +.....#...............................................................................................................#..............#......# +...........#.......................................#.....#.................#.................#.............................................. +............................................................................................................................................ +.#.......................................#..........................................#................#...................................... +......................#.............#.................#.......................#...........#.............................#................... +...............#.............#................................#......#.......................................................#.............. +............................................................................................................................................ +...#............................................................................................#....................#...................... +..........#.....................#.............................................................................#............................. +...........................#...............................................................................................#...............# +.....................#......................................#.......#......#........#..................#...........................#........ +.....#...............................#............#......................................................................................... +............................................................................................................................................ +.........................................................#........................................................#......................... +#..............................#..........#..............................................................................#................#. +....................#..............................................#.......................#.........#...................................... +............................................................................................................................................ +...........#.......................................#.............................................................................#.......... +...#......................#...............................................#......................#.......................................... +..................#......................................................................................................................... +...........................................................#........#...........#.....#......#........................#.................#... +........#................................................................................................................................... +....................................................................................................#......#................................ +................................#...........#....................#.....#...................................................#........#....... +........................#............#......................................#.............#................................................. +...................#............................................................................................#........................... +#................................................................................................................................#.......... +..............#.............................................#............................................................................... +..............................#...............................................#.................#......................................#.... +....#....................#......................................#...................#...............................#.......#............... +........................................#..........#........................................#................#.............................. +............................................................................................................................................ +............................................................................................................................................ +........................................................................................................................................#... +...........................................................#..................#.................#.................#......................... +.......#........................................................#................................................................#.......... +..........................#......#......#..................................................................................#................ +...............................................#.....#.................#.................................................................... +......................................................................................................#..................................... +................#....................#.....................................................................#........#....................... +..............................................................................................................................#............. +...........................................#.............................................................................................#.. +....#........................#..............................#.............#................#................................................ +......................#..........................................................................................#......#................... +....................................................#................................#.........#............................................ +..........................#.......................................#......................................................................... +.................#........................#.....#........................................................#.................................. +.#.........................................................#............#....................................................#.............. +..........#..................#.....#..................................................................................................#..... +.................................................................................#.......................................................... +.....................................................#....................................#.........#...........#.....#..................... +.............................................#.....................#.......................................#.......................#........ +................................#........................................................................................................... +......#........................................................#..............................#............................................. +............#......................................#.....#............................#........................................#............ +............................................................................#............................................................... +.......................................#...............................#...................#..............................#...........#..... +.......................#..............................#..........................#..............................#........................... +.................................................................#...................................#...................................... +......................................................................................................................#...................#. +.................#.......................................................................................................................... +.........#......................#.....#...........#.......................................................#................................. +...........................................#.................#................#.....................................................#....... +..#...............................................................#......................................................................... +.....................#......#......#.............................................................#............#...........#................. diff --git a/aoc2023/src/day11.rs b/aoc2023/src/day11.rs new file mode 100644 index 0000000..be28937 --- /dev/null +++ b/aoc2023/src/day11.rs @@ -0,0 +1,145 @@ +use aoc_runner_derive::{aoc, aoc_generator}; + +#[aoc_generator(day11, part1)] +fn parse1(input: &str) -> Vec<(usize, usize)> { + utils::parse_expanded_galaxies(input, 1) +} + +#[aoc(day11, part1)] +fn part1(input: &[(usize, usize)]) -> usize { + utils::sum_galactic_distances(input) +} + +#[aoc_generator(day11, part2)] +fn parse2(input: &str) -> Vec<(usize, usize)> { + utils::parse_expanded_galaxies(input, 999_999) +} + +#[aoc(day11, part2)] +fn part2(input: &[(usize, usize)]) -> usize { + utils::sum_galactic_distances(input) +} + +mod utils { + pub fn parse_expanded_galaxies(input: &str, expansion_rate: usize) -> Vec<(usize, usize)> { + let expanding_rows = find_expanding_rows(input); + let expanding_cols = find_expanding_cols(input); + let galaxies = find_galaxies(input); + + expand_universe(&galaxies, &expanding_rows, &expanding_cols, expansion_rate) + } + + pub fn sum_galactic_distances(galaxies: &[(usize, usize)]) -> usize { + use itertools::Itertools; + galaxies + .iter() + .combinations(2) + .map(|pair| { + // Manhattan distance + let (galaxy_a, galaxy_b) = (pair[0], pair[1]); + let (dx, dy) = ( + galaxy_a.0.abs_diff(galaxy_b.0), + galaxy_a.1.abs_diff(galaxy_b.1), + ); + dx + dy + }) + .sum() + } + + fn find_expanding_rows(input: &str) -> Vec { + input + .lines() + .enumerate() + .filter(|(_, line)| line.chars().all(|c| c == '.')) + .map(|(x, _)| x) + .collect() + } + + fn find_expanding_cols(input: &str) -> Vec { + let mut expanding_cols = Vec::new(); + 'outer: for y in 0..input.lines().next().unwrap().chars().count() { + for x in 0..input.lines().count() { + if input.lines().nth(x).unwrap().chars().nth(y).unwrap() == '#' { + continue 'outer; + } + } + expanding_cols.push(y); + } + expanding_cols + } + + fn find_galaxies(input: &str) -> Vec<(usize, usize)> { + let mut galaxies = Vec::new(); + for (y, line) in input.lines().enumerate() { + for (x, c) in line.chars().enumerate() { + if c == '#' { + galaxies.push((x, y)); + } + } + } + galaxies + } + + fn expand_universe( + galaxies: &[(usize, usize)], + expanding_rows: &[usize], + expanding_cols: &[usize], + expasion_rate: usize, + ) -> Vec<(usize, usize)> { + let (x_limit, y_limit) = ( + galaxies.iter().max_by_key(|(x, _)| x).unwrap().0 + 1, + galaxies.iter().max_by_key(|(_, y)| y).unwrap().1 + 1, + ); + + let mut expanded_galaxies = Vec::new(); + let mut n_expanded_rows = 0; + let mut n_expanded_cols = 0; + for y in 0..y_limit { + if expanding_rows.contains(&y) { + n_expanded_rows += expasion_rate; + continue; + } + for x in 0..x_limit { + if expanding_cols.contains(&x) { + n_expanded_cols += expasion_rate; + continue; + } + if galaxies.contains(&(x, y)) { + expanded_galaxies.push((x + n_expanded_cols, y + n_expanded_rows)); + } + } + n_expanded_cols = 0; + } + expanded_galaxies + } +} + +#[cfg(test)] +mod tests { + use super::*; + use indoc::indoc; + + const SAMPLE: &str = indoc! {" + ...#...... + .......#.. + #......... + .......... + ......#... + .#........ + .........# + .......... + .......#.. + #...#..... + "}; + + #[test] + fn part1_example() { + assert_eq!(part1(&parse1(SAMPLE)), 374); + } + + #[test] + fn part2_example() { + assert_eq!(part2(&utils::parse_expanded_galaxies(SAMPLE, 9)), 1030); + assert_eq!(part2(&utils::parse_expanded_galaxies(SAMPLE, 99)), 8410); + } +} diff --git a/aoc2023/src/lib.rs b/aoc2023/src/lib.rs index 344502b..b7ad95e 100644 --- a/aoc2023/src/lib.rs +++ b/aoc2023/src/lib.rs @@ -1,5 +1,6 @@ pub mod day1; pub mod day10; +pub mod day11; pub mod day2; pub mod day3; pub mod day4;