day09 modules

This commit is contained in:
Stefan Schwarz 2020-12-16 23:22:02 +01:00
parent decff21434
commit d45577b935
3 changed files with 82 additions and 76 deletions

13
src/day09/errors.rs Normal file
View file

@ -0,0 +1,13 @@
use thiserror::Error;
#[derive(Error, Debug)]
pub enum Errors {
#[error("invalid input")]
InvalidInput,
}
impl From<std::num::ParseIntError> for Errors {
fn from(_: std::num::ParseIntError) -> Self {
Errors::InvalidInput
}
}

View file

@ -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<i64>,
}
impl TryFrom<&str> for XMASDecoder {
type Error = Errors;
fn try_from(input: &str) -> Result<Self, Self::Error> {
let input = input
.split_ascii_whitespace()
.map(|line| line.trim().parse::<i64>())
.collect::<std::result::Result<Vec<i64>, _>>()?;
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<i64> {
self.input
.windows(26)
.into_iter()
.filter_map(Self::validate_slice)
.next()
}
fn validate_slice(window: &[i64]) -> Option<i64> {
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<std::num::ParseIntError> for Errors {
fn from(_: std::num::ParseIntError) -> Self {
Errors::InvalidInput
}
}

65
src/day09/xmas_decoder.rs Normal file
View file

@ -0,0 +1,65 @@
use std::convert::TryFrom;
use super::errors;
pub struct XMASDecoder {
input: Vec<i64>,
}
impl TryFrom<&str> for XMASDecoder {
type Error = errors::Errors;
fn try_from(input: &str) -> Result<Self, Self::Error> {
let input = input
.split_ascii_whitespace()
.map(|line| line.trim().parse::<i64>())
.collect::<std::result::Result<Vec<i64>, _>>()?;
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<i64> {
self.input
.windows(26)
.into_iter()
.filter_map(Self::validate_slice)
.next()
}
fn validate_slice(window: &[i64]) -> Option<i64> {
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)
}
}