day09 modules
This commit is contained in:
parent
decff21434
commit
d45577b935
3 changed files with 82 additions and 76 deletions
13
src/day09/errors.rs
Normal file
13
src/day09/errors.rs
Normal 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
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,11 +1,13 @@
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use std::convert::TryFrom;
|
use std::convert::TryFrom;
|
||||||
use thiserror::Error;
|
|
||||||
|
pub mod xmas_decoder;
|
||||||
|
pub mod errors;
|
||||||
|
|
||||||
static INPUT: &str = include_str!("../../input09");
|
static INPUT: &str = include_str!("../../input09");
|
||||||
|
|
||||||
fn main() -> Result<()> {
|
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");
|
let missing = decoder.decode().expect("did not find a solution");
|
||||||
println!("missing: {}", missing);
|
println!("missing: {}", missing);
|
||||||
|
@ -19,77 +21,3 @@ fn main() -> Result<()> {
|
||||||
Ok(())
|
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
65
src/day09/xmas_decoder.rs
Normal 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)
|
||||||
|
}
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue