diff --git a/src/day09/errors.rs b/src/day09/errors.rs new file mode 100644 index 0000000..6804f9c --- /dev/null +++ b/src/day09/errors.rs @@ -0,0 +1,13 @@ +use thiserror::Error; + +#[derive(Error, Debug)] +pub enum Errors { + #[error("invalid input")] + InvalidInput, +} + +impl From for Errors { + fn from(_: std::num::ParseIntError) -> Self { + Errors::InvalidInput + } +} diff --git a/src/day09/main.rs b/src/day09/main.rs index 6db5201..1838bd3 100644 --- a/src/day09/main.rs +++ b/src/day09/main.rs @@ -1,11 +1,13 @@ use anyhow::Result; use std::convert::TryFrom; -use thiserror::Error; + +pub mod xmas_decoder; +pub mod errors; static INPUT: &str = include_str!("../../input09"); fn main() -> Result<()> { - let decoder = XMASDecoder::try_from(INPUT)?; + let decoder = xmas_decoder::XMASDecoder::try_from(INPUT)?; let missing = decoder.decode().expect("did not find a solution"); println!("missing: {}", missing); @@ -19,77 +21,3 @@ fn main() -> Result<()> { Ok(()) } -pub struct XMASDecoder { - input: Vec, -} - -impl TryFrom<&str> for XMASDecoder { - type Error = Errors; - - fn try_from(input: &str) -> Result { - let input = input - .split_ascii_whitespace() - .map(|line| line.trim().parse::()) - .collect::, _>>()?; - Ok(Self { input }) - } -} - -impl XMASDecoder { - pub fn find_continues(&self, target: i64) -> Option<&[i64]> { - for offset in 0..self.input.len() { - let slice = &self.input[offset..self.input.len()]; - if let Some(found) = Self::find_sum_slice(slice, target) { - return Some(found); - } - } - None - } - - fn find_sum_slice(slice: &[i64], target: i64) -> Option<&[i64]> { - let mut offset = 0; - let mut sum = 0; - for i in slice { - offset += 1; - sum += *i; - if sum == target { - return Some(&slice[0..offset]); - } else if sum > target { - return None; - } - } - None - } - - pub fn decode(&self) -> Option { - self.input - .windows(26) - .into_iter() - .filter_map(Self::validate_slice) - .next() - } - - fn validate_slice(window: &[i64]) -> Option { - let (target, slice) = window.split_last().unwrap(); - for (offset, a) in slice.iter().enumerate() { - for b in slice[offset + 1..slice.len()].iter() { - if a + b == *target { - return None; - } - } - } - Some(*target) - } -} - -#[derive(Error, Debug)] -pub enum Errors { - #[error("invalid input")] - InvalidInput, -} - -impl From for Errors { - fn from(_: std::num::ParseIntError) -> Self { - Errors::InvalidInput - } -} diff --git a/src/day09/xmas_decoder.rs b/src/day09/xmas_decoder.rs new file mode 100644 index 0000000..355192c --- /dev/null +++ b/src/day09/xmas_decoder.rs @@ -0,0 +1,65 @@ +use std::convert::TryFrom; +use super::errors; + +pub struct XMASDecoder { + input: Vec, +} + +impl TryFrom<&str> for XMASDecoder { + type Error = errors::Errors; + + fn try_from(input: &str) -> Result { + let input = input + .split_ascii_whitespace() + .map(|line| line.trim().parse::()) + .collect::, _>>()?; + Ok(Self { input }) + } +} + +impl XMASDecoder { + pub fn find_continues(&self, target: i64) -> Option<&[i64]> { + for offset in 0..self.input.len() { + let slice = &self.input[offset..self.input.len()]; + if let Some(found) = Self::find_sum_slice(slice, target) { + return Some(found); + } + } + None + } + + fn find_sum_slice(slice: &[i64], target: i64) -> Option<&[i64]> { + let mut offset = 0; + let mut sum = 0; + for i in slice { + offset += 1; + sum += *i; + if sum == target { + return Some(&slice[0..offset]); + } else if sum > target { + return None; + } + } + None + } + + pub fn decode(&self) -> Option { + self.input + .windows(26) + .into_iter() + .filter_map(Self::validate_slice) + .next() + } + + fn validate_slice(window: &[i64]) -> Option { + let (target, slice) = window.split_last().unwrap(); + for (offset, a) in slice.iter().enumerate() { + for b in slice[offset + 1..slice.len()].iter() { + if a + b == *target { + return None; + } + } + } + Some(*target) + } +}