diff --git a/README.md b/README.md index 636d0e8..80f2916 100644 --- a/README.md +++ b/README.md @@ -15,17 +15,17 @@ My solutions to [Advent of Code](https://adventofcode.com) puzzles. > All benchmarks are run on a *Dell Precision 5550* laptop with an *Intel Core i7-10875H* CPU. -| D | Puzzle | Code | Part 1 Performance | Part 2 Performance | -| :---: | --------------------------------------------------------- | :----------------------------: | :----------------: | :----------------: | -| 1 | [Historian Hysteria](https://adventofcode.com/2024/day/1) | [day1.rs](aoc2024/src/day1.rs) | 92.26 µs | 69.56 µs | -| 2 | [Red-Nosed Reports](https://adventofcode.com/2024/day/2) | [day2.rs](aoc2024/src/day2.rs) | 67.96 µs | 141.4 µs | -| 3 | [Mull It Over](https://adventofcode.com/2024/day/3) | [day3.rs](aoc2024/src/day3.rs) | 81.17 µs | 79.13 µs | -| 4 | [Ceres Search](https://adventofcode.com/2024/day/4) | [day4.rs](aoc2024/src/day4.rs) | 257.6 µs | 142.3 µs | -| 5 | [Print Queue](https://adventofcode.com/2024/day/5) | [day5.rs](aoc2024/src/day5.rs) | 98.64 µs | 133.9 µs | -| 6 | [Guard Gallivant](https://adventofcode.com/2024/day/6) | [day6.rs](aoc2024/src/day6.rs) | 39.48 µs | 6.768 ms | -| 7 | [Bridge Repair](https://adventofcode.com/2024/day/7) | [day7.rs](aoc2024/src/day7.rs) | 824.2 µs | 49.06 ms | - - +| D | Puzzle | Code | Part 1 Performance | Part 2 Performance | +| :---: | ------------------------------------------------------------ | :----------------------------: | :----------------: | :----------------: | +| 1 | [Historian Hysteria](https://adventofcode.com/2024/day/1) | [day1.rs](aoc2024/src/day1.rs) | 92.26 µs | 69.56 µs | +| 2 | [Red-Nosed Reports](https://adventofcode.com/2024/day/2) | [day2.rs](aoc2024/src/day2.rs) | 67.96 µs | 141.4 µs | +| 3 | [Mull It Over](https://adventofcode.com/2024/day/3) | [day3.rs](aoc2024/src/day3.rs) | 81.17 µs | 79.13 µs | +| 4 | [Ceres Search](https://adventofcode.com/2024/day/4) | [day4.rs](aoc2024/src/day4.rs) | 257.6 µs | 142.3 µs | +| 5 | [Print Queue](https://adventofcode.com/2024/day/5) | [day5.rs](aoc2024/src/day5.rs) | 98.64 µs | 133.9 µs | +| 6 | [Guard Gallivant](https://adventofcode.com/2024/day/6) | [day6.rs](aoc2024/src/day6.rs) | 39.48 µs | 6.768 ms | +| 7 | [Bridge Repair](https://adventofcode.com/2024/day/7) | [day7.rs](aoc2024/src/day7.rs) | 824.2 µs | 49.06 ms | +| 8 | [Resonant Collinearity](https://adventofcode.com/2024/day/8) | [day8.rs](aoc2024/src/day8.rs) | 40.13 µs | 36.43 µs | + diff --git a/aoc2024/input/2024/day8.txt b/aoc2024/input/2024/day8.txt new file mode 100644 index 0000000..c671bf8 --- /dev/null +++ b/aoc2024/input/2024/day8.txt @@ -0,0 +1,50 @@ +.............4....O..........w....R............... +.................................f................ +..............4...j......NW0...................... +....................R..W.......................... +...............R.................................. +.................................................. +v.......................f.......0W................ +.....9L............l...N.........w................ +....L....9.......ON........8...................... +.1.........49L........f..0..N..................... +..........................V...l................... +..........4....................................... +.....................j...................3.....U.. +....O.....U....................................... +........J......................l.................. +.O....s.Q.......j.....l.....w..........F...q...... +.................................................. +.U.......................j..8..................... +................U...............................3. +2.............................J............3...... +..............................F................... +.....s...R...........J..................F......... +.s......................x..........F.....q........ +.......2.....Q........3........x.................. +...........v......................u............... +..............v...........n......8............q... +.......f..................8........i.............. +.5..................1n..............P.....i....... +............7............Q..................X..... +......5...p....................V.................. +.................J..........nx............q....... +.......p............W...........................0. +......2.............p.5.....1....P................ +......I.................7.X....i...P.............. +............s.....r...w................V.......... +...............or...6.................V........... +............................PS.7.................. +..........o...........................S........... +...........5..............o..1.......n............ +...........I.........r.......7.......6............ +.................o.r...........X.................. +................................x.........u....... +.........p..Q....2................................ +.........v.................S.....................u +I...........................S.....6............... +.................................................. +.......I.......................................... +.................................................. +.......................................6.......... +.................................X................ diff --git a/aoc2024/src/day8.rs b/aoc2024/src/day8.rs new file mode 100644 index 0000000..59db801 --- /dev/null +++ b/aoc2024/src/day8.rs @@ -0,0 +1,130 @@ +use aoc_runner_derive::aoc; +use itertools::Itertools; + +#[aoc(day8, part1)] +#[must_use] +pub fn part1(input: &str) -> usize { + let map = Map::parse(input); + map.nodes() + .iter() + .filter(|node| !node.is_empty()) + .flat_map(|node| { + node.iter() + .permutations(2) + .map(|pair| (pair[0], pair[1])) + .filter_map(|(&(x1, y1), &(x2, y2))| { + if let (Some(x), Some(y)) = ((2 * x2).checked_sub(x1), (2 * y2).checked_sub(y1)) + { + if x < map.ncols() && y < map.nrows() { + return Some((x, y)); + } + } + None + }) + }) + .collect::>() + .len() +} + +#[aoc(day8, part2)] +#[must_use] +pub fn part2(input: &str) -> usize { + let map = Map::parse(input); + let (ncols, nrows) = (map.ncols() as i16, map.nrows() as i16); + map.nodes() + .iter() + .filter(|node| !node.is_empty()) + .flat_map(|node| { + node.iter() + .permutations(2) + .map(|pair| (pair[0], pair[1])) + .flat_map(|(&(x1, y1), &(x2, y2))| { + let (x1, y1, x, y) = (x1 as i16, y1 as i16, x2 as i16, y2 as i16); + let (dx, dy) = ((x - x1), (y - y1)); + std::iter::successors(Some((x, y)), move |(x, y)| { + let (x, y) = (x + dx, y + dy); + if x >= 0 && y >= 0 && x < ncols && y < nrows { + return Some((x, y)); + } + None + }) + }) + }) + .collect::>() + .len() +} + +#[repr(transparent)] +#[derive(Clone, derive_more::Deref, derive_more::DerefMut)] +struct Map(nalgebra::DMatrix); + +impl Map { + fn parse(input: &str) -> Self { + let input = input.as_bytes(); + let width = input.iter().position(|&c| c == b'\n').unwrap(); + let mut map = nalgebra::DMatrix::from_element(width, input.len() / width, b'.'); + input.chunks(width + 1).enumerate().for_each(|(y, line)| { + line.iter().enumerate().for_each(|(x, c)| match c { + b'.' | b'\n' => {} + _ => map[(x, y)] = *c, + }); + }); + Self(map) + } + + fn nodes(&self) -> [smallvec::SmallVec<[(usize, usize); 4]>; u8::MAX as usize] { + let mut nodes = std::array::from_fn(|_| smallvec::SmallVec::new()); + (0..self.ncols()) + .cartesian_product(0..self.nrows()) + .filter(|&(y, x)| self[(x, y)] != b'.') + .for_each(|(y, x)| { + nodes[self[(x, y)] as usize].push((x, y)); + }); + nodes + } +} + +#[cfg(test)] +mod tests { + use super::*; + use indoc::indoc; + + const SAMPLE: &str = indoc! {" + ............ + ........0... + .....0...... + .......0.... + ....0....... + ......A..... + ............ + ............ + ........A... + .........A.. + ............ + ............ + "}; + + const SAMPLE2: &str = indoc! {" + T......... + ...T...... + .T........ + .......... + .......... + .......... + .......... + .......... + .......... + .......... + "}; + + #[test] + pub fn part1_example() { + assert_eq!(part1(SAMPLE), 14); + } + + #[test] + pub fn part2_example() { + assert_eq!(part2(SAMPLE), 34); + assert_eq!(part2(SAMPLE2), 9); + } +} diff --git a/aoc2024/src/lib.rs b/aoc2024/src/lib.rs index 12cd076..29fcc3e 100644 --- a/aoc2024/src/lib.rs +++ b/aoc2024/src/lib.rs @@ -5,7 +5,7 @@ pub mod day4; pub mod day5; pub mod day6; pub mod day7; -// pub mod day8; +pub mod day8; // pub mod day9; // pub mod day10;