diff options
author | Toby Vincent <tobyv@tobyvin.dev> | 2023-12-09 14:48:15 -0600 |
---|---|---|
committer | Toby Vincent <tobyv@tobyvin.dev> | 2023-12-09 14:48:15 -0600 |
commit | 2c1a72d833fbd4b30b0f4c3ada82202317b50269 (patch) | |
tree | eb8f43191079f8b788292df5707c15d86c11b3ca /src | |
parent | 6d31120a46210275970200b96b25499bd37530c9 (diff) |
feat: impl day 9
Diffstat (limited to 'src')
-rw-r--r-- | src/day_08.rs | 1 | ||||
-rw-r--r-- | src/day_09.rs | 77 | ||||
-rw-r--r-- | src/lib.rs | 1 | ||||
-rw-r--r-- | src/main.rs | 3 |
4 files changed, 81 insertions, 1 deletions
diff --git a/src/day_08.rs b/src/day_08.rs index 167d951..7652a77 100644 --- a/src/day_08.rs +++ b/src/day_08.rs @@ -141,6 +141,7 @@ mod tests { } #[test] + #[ignore] fn test_part_2() -> anyhow::Result<()> { const INPUT: &str = indoc::indoc! {" LR diff --git a/src/day_09.rs b/src/day_09.rs new file mode 100644 index 0000000..78cf69a --- /dev/null +++ b/src/day_09.rs @@ -0,0 +1,77 @@ +use std::{num::ParseIntError, str::FromStr}; + +use crate::{Problem, Solution}; + +pub struct Day09; + +impl Problem for Day09 { + const DAY: u8 = 9; + + const INPUT: &'static str = include_str!("../input/day_09.txt"); +} + +impl Solution for Day09 { + type Answer1 = isize; + + type Answer2 = isize; + + fn part_1(input: &str) -> anyhow::Result<Self::Answer1> { + let data = parse_input(input)?; + Ok(data.into_iter().map(extrapolate_forward).sum()) + } + + fn part_2(input: &str) -> anyhow::Result<Self::Answer2> { + let data = parse_input(input)?; + Ok(data.into_iter().map(extrapolate_reverse).sum()) + } +} + +fn parse_input(input: &str) -> Result<Vec<Vec<isize>>, ParseIntError> { + input.trim().lines().map(parse_line).collect() +} + +fn parse_line(line: &str) -> Result<Vec<isize>, ParseIntError> { + line.split_whitespace().map(FromStr::from_str).collect() +} + +fn extrapolate_forward(mut values: Vec<isize>) -> isize { + let mut value = 0; + + while values.iter().any(|n| *n != 0) { + value += values.last().copied().unwrap(); + values = values.array_windows().map(|[n, m]| m - n).collect(); + } + value +} + +fn extrapolate_reverse(mut values: Vec<isize>) -> isize { + let mut tails = Vec::new(); + + while values.iter().any(|n| *n != 0) { + tails.push(values.first().copied().unwrap()); + values = values.array_windows().map(|[n, m]| m - n).collect(); + } + + tails.into_iter().rev().fold(0, |acc, n| n - acc) +} + +#[cfg(test)] +mod tests { + use super::*; + + const INPUT: &str = indoc::indoc! {" + 0 3 6 9 12 15 + 1 3 6 10 15 21 + 10 13 16 21 30 45 + "}; + + #[test] + fn test_part_1() -> anyhow::Result<()> { + Ok(assert_eq!(114, Day09::part_1(INPUT)?)) + } + + #[test] + fn test_part_2() -> anyhow::Result<()> { + Ok(assert_eq!(2, Day09::part_2(INPUT)?)) + } +} @@ -8,6 +8,7 @@ pub mod day_05; pub mod day_06; pub mod day_07; pub mod day_08; +pub mod day_09; pub trait Problem { const DAY: u8; diff --git a/src/main.rs b/src/main.rs index 52da9eb..fa19b95 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,6 +1,6 @@ use aoc_2023::{ day_01::Day01, day_02::Day02, day_03::Day03, day_04::Day04, day_05::Day05, day_06::Day06, - day_07::Day07, day_08::Day08, Solution, + day_07::Day07, day_08::Day08, day_09::Day09, Solution, }; fn main() -> anyhow::Result<()> { @@ -12,6 +12,7 @@ fn main() -> anyhow::Result<()> { Day06::solve()?; Day07::solve()?; Day08::solve()?; + Day09::solve()?; Ok(()) } |