This commit is contained in:
Stefan Schwarz 2020-12-16 23:08:06 +01:00
parent 497f281e02
commit decff21434
3 changed files with 1099 additions and 0 deletions

View file

@ -43,3 +43,7 @@ path = "src/day07/main.rs"
[[bin]] [[bin]]
name = "day08" name = "day08"
path = "src/day08/main.rs" path = "src/day08/main.rs"
[[bin]]
name = "day09"
path = "src/day09/main.rs"

1000
input09 Normal file

File diff suppressed because it is too large Load diff

95
src/day09/main.rs Normal file
View file

@ -0,0 +1,95 @@
use anyhow::Result;
use std::convert::TryFrom;
use thiserror::Error;
static INPUT: &str = include_str!("../../input09");
fn main() -> Result<()> {
let decoder = XMASDecoder::try_from(INPUT)?;
let missing = decoder.decode().expect("did not find a solution");
println!("missing: {}", missing);
let found = decoder
.find_continues(missing)
.expect("did not find a solution");
let sum = found.iter().max().unwrap() + found.iter().min().unwrap();
println!("sum: {}", sum);
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
}
}