diff --git a/README.md b/README.md index e2511d5..6d57704 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ [![Language: Rust](https://img.shields.io/badge/Language-Rust-orange.svg?style=flat-square)](https://en.wikipedia.org/wiki/Rust_(programming_language)) [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg?style=flat-square)](https://mit-license.org/) ![Days completed](https://img.shields.io/badge/Days%20completed-1-red?style=flat-square) -![Stars](https://img.shields.io/badge/Stars-2-yellow?style=flat-square) +![Stars](https://img.shields.io/badge/Stars-3-yellow?style=flat-square) > ⚠️ This README is copied from my previous years solution. It is not fully adopted to 2024 yet. diff --git a/src/days/d02.rs b/src/days/d02.rs index bc6dd3d..91d4497 100644 --- a/src/days/d02.rs +++ b/src/days/d02.rs @@ -2,31 +2,118 @@ use super::{Answer, Day, DayImpl}; const CURRENT_DAY: u8 = 2; -type Data = Vec; +pub enum Direction { + Increasing, + Decreasing, +} + +#[derive(Clone, Debug)] +pub struct Report(Vec); + +impl Report { + pub fn is_safe(&self, tolerance: usize) -> bool { + let mut direction = None; + let mut failures = 0; + let mut skip_last = false; + + for i in 1..self.0.len() { + match ( + self.0[i] + - self.0[i - if skip_last { + skip_last = false; + 2 + } else { + 1 + }], + &direction, + ) { + /* Over limits */ + (..=-4 | 4.., _) => { + failures += 1; + skip_last = true; + } + + /* Decide on direction */ + (..=-1, None) => direction = Some(Direction::Decreasing), + (1.., None) => direction = Some(Direction::Increasing), + + /* Wrong Direction */ + (1.., Some(Direction::Decreasing)) => { + failures += 1; + skip_last = true; + } + (..=-1, Some(Direction::Increasing)) => { + failures += 1; + skip_last = true; + } + + /* No Change */ + (0, _) => { + failures += 1; + skip_last = true; + } + _ => {} + } + + if failures > tolerance { + return false; + } + + if skip_last { + println!("SKIPPING {}", i); + } + } + true + } +} + +impl From<&str> for Report { + fn from(value: &str) -> Self { + Self( + value + .split_whitespace() + .map(|v| v.parse::().expect("error while parsing input.")) + .collect(), + ) + } +} + +type Data = Vec; impl DayImpl for Day { fn init_test() -> (Self, Data) { Self::init(include_str!("test_inputs/test02.txt")) } fn expected_results() -> (Answer, Answer) { - (Answer::Number(0), Answer::Number(0)) + (Answer::Number(2), Answer::Number(4)) } fn init(input: &str) -> (Self, Data) { - ( - Self {}, - input - .lines() - .map(|v| v.parse::().expect("error while parsing input.")) - .collect(), - ) + (Self {}, input.lines().map(|l| l.into()).collect()) } fn one(&self, data: &mut Data) -> Answer { - Answer::Number(data.len() as u64) + let mut safe_count = 0; + for report in data { + println!("{:?}", report); + if report.is_safe(0) { + safe_count += 1; + } + } + + return Answer::Number(safe_count); } fn two(&self, data: &mut Data) -> Answer { - Answer::Number(data.len() as u64) + let mut safe_count = 0; + for report in data { + println!("{:?}", report); + if report.is_safe(1) { + println!("Safe!"); + safe_count += 1; + } + } + + return Answer::Number(safe_count); } } diff --git a/src/days/test_inputs/test02.txt b/src/days/test_inputs/test02.txt index e69de29..b49c10d 100644 --- a/src/days/test_inputs/test02.txt +++ b/src/days/test_inputs/test02.txt @@ -0,0 +1,6 @@ +7 6 4 2 1 +1 2 7 8 9 +9 7 6 2 1 +1 3 2 4 5 +8 6 4 4 1 +1 3 6 7 9