You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

121 lines
2.7 KiB
Rust

#[derive(Copy, Clone, PartialEq, Debug)]
pub enum Status
{
Safe,
Unsafe,
Unknown,
}
#[derive(Clone, Debug)]
pub struct Report
{
levels: Vec<i32>,
status: Status,
enable_dampener: bool,
}
//|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
// IMPL Report
//|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
impl Report
{
pub fn new(lvls: Vec<i32>, 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<i32>, 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
}