diff --git a/README.md b/README.md index 5f7754f..cc03a07 100644 --- a/README.md +++ b/README.md @@ -24,16 +24,17 @@ Solutions for [Advent of Code](https://adventofcode.com/) in [Rust](https://www. | Day | Part 1 | Part 2 | | :---: | :---: | :---: | -| [Day 1](./src/bin/01.rs) | `33.6µs` | `36.1µs` | -| [Day 2](./src/bin/02.rs) | `42.5µs` | `41.8µs` | -| [Day 3](./src/bin/03.rs) | `84.6µs` | `99.7µs` | -| [Day 4](./src/bin/04.rs) | `48.6µs` | `51.3µs` | -| [Day 5](./src/bin/05.rs) | `20.7µs` | `24.3µs` | -| [Day 6](./src/bin/06.rs) | `202.0ns` | `102.0ns` | -| [Day 7](./src/bin/07.rs) | `95.9µs` | `92.6µs` | -| [Day 8](./src/bin/08.rs) | `74.5µs` | `159.3µs` | - -**Total: 0.91ms** +| [Day 1](./src/bin/01.rs) | `33.3µs` | `35.8µs` | +| [Day 2](./src/bin/02.rs) | `42.5µs` | `40.5µs` | +| [Day 3](./src/bin/03.rs) | `82.7µs` | `97.8µs` | +| [Day 4](./src/bin/04.rs) | `48.2µs` | `49.5µs` | +| [Day 5](./src/bin/05.rs) | `20.4µs` | `24.4µs` | +| [Day 6](./src/bin/06.rs) | `203.0ns` | `102.0ns` | +| [Day 7](./src/bin/07.rs) | `93.9µs` | `94.0µs` | +| [Day 8](./src/bin/08.rs) | `73.0µs` | `160.4µs` | +| [Day 9](./src/bin/09.rs) | `58.0µs` | `57.5µs` | + +**Total: 1.01ms** --- diff --git a/data/examples/09.txt b/data/examples/09.txt new file mode 100644 index 0000000..70c5595 --- /dev/null +++ b/data/examples/09.txt @@ -0,0 +1,3 @@ +0 3 6 9 12 15 +1 3 6 10 15 21 +10 13 16 21 30 45 \ No newline at end of file diff --git a/src/bin/09.rs b/src/bin/09.rs new file mode 100644 index 0000000..eef35ae --- /dev/null +++ b/src/bin/09.rs @@ -0,0 +1,77 @@ +use rayon::{iter::ParallelIterator, str::ParallelString}; + +advent_of_code::solution!(9); + +pub fn part_one(input: &str) -> Option { + Some( + input + .par_lines() + .map(|line| { + let nums = line + .split_whitespace() + .map(|ch| ch.parse::().expect("should be a number")) + .collect::>(); + find_next(nums) + }) + .sum(), + ) +} + +pub fn part_two(input: &str) -> Option { + Some( + input + .par_lines() + .map(|line| { + let nums = line + .split_whitespace() + .rev() + .map(|ch| ch.parse::().expect("should be a number")) + .collect::>(); + find_next(nums) + }) + .sum(), + ) +} + +fn find_next(input: Vec) -> i32 { + let Some(&last_value) = input.last() else { + return 0; + }; + let mut differences = input; + let mut last_difference_sum = 0; + while differences.len() > 1 { + let mut all_zeros = true; + for i in 1..differences.len() { + let difference = differences[i] - differences[i - 1]; + if difference != 0 { + all_zeros = false; + } + differences[i - 1] = difference; + if i == differences.len() - 1 { + last_difference_sum += difference; + } + } + if all_zeros { + break; + } + differences.pop(); + } + last_value + last_difference_sum +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_part_one() { + let result = part_one(&advent_of_code::template::read_file("examples", DAY)); + assert_eq!(result, Some(114)); + } + + #[test] + fn test_part_two() { + let result = part_two(&advent_of_code::template::read_file("examples", DAY)); + assert_eq!(result, Some(2)); + } +}