#[derive(Copy, Clone, PartialEq, Debug)] pub enum Status { Safe, Unsafe, Unknown, } #[derive(Clone, Debug)] pub struct Report { levels: Vec, status: Status, enable_dampener: bool, } //||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| // IMPL Report //||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| impl Report { pub fn new(lvls: Vec, enable_dampener: bool) -> Report { Report { levels: lvls , status: Status::Unknown, enable_dampener } } pub fn analyze(self: &mut Report, enable_debug_prints: bool) -> Status { if self.enable_dampener { // Brute force the dampener thing let mut i = 0; let mut status = check_levels(&self.levels, enable_debug_prints); while i < self.levels.len() && status == Status::Unsafe { let mut levels = self.levels.clone(); levels.remove(i); status = check_levels(&levels, enable_debug_prints); i += 1; } self.status = status; } else { self.status = check_levels(&self.levels, enable_debug_prints); } return self.status; } fn _try_dampen_level(self: &mut Report, at: usize, do_debug_prints: bool) -> bool { if !self.enable_dampener { return false; } if do_debug_prints { println!("Day 2 DEBUG: Bad level detected in report ({:#?}), using dampener to remove level: {}", self.levels, self.levels[at]); } self.levels.remove(at); self.enable_dampener = false; return true; } } //||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| // HELPERS //||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| // SAFTY RULES: // The levels are either all increasing or all decreasing. // Any two adjacent levels differ by at least one and at most three. fn check_levels(levels: &Vec, enable_debug_prints: bool) -> Status { let mut prev_direction = 0; let mut i = 0; while i < levels.len() - 1 // Don't process the last level value { let diff = levels[i] - levels[i + 1]; let this_direction = if diff > 0 { 1 } else if diff < 0 { -1 } else { 0 }; // diff check let diff = diff.abs(); if diff > 3 || diff < 1 { if enable_debug_prints { println!("Day 2 DEBUG: Report ({:#?}) is unsafe due to invalid value gap ({}): {} to {}", levels, diff, levels[i], levels[i + 1]) } return Status::Unsafe; } // increase/decrease check if 0 == prev_direction { prev_direction = this_direction } else { if prev_direction != this_direction { if enable_debug_prints { println!("Day 2 DEBUG: Report ({:#?}) is unsafe due to increase/decrease rule violation: {} to {}", levels, levels[i], levels[i + 1]) } return Status::Unsafe; } } i += 1; } Status::Safe }