day9
This commit is contained in:
parent
497f281e02
commit
decff21434
3 changed files with 1099 additions and 0 deletions
|
@ -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"
|
||||||
|
|
95
src/day09/main.rs
Normal file
95
src/day09/main.rs
Normal 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
|
||||||
|
}
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue