|
|
|
@ -14,84 +14,45 @@ pub struct Report
|
|
|
|
levels: Vec<i32>,
|
|
|
|
levels: Vec<i32>,
|
|
|
|
status: Status,
|
|
|
|
status: Status,
|
|
|
|
enable_dampener: bool,
|
|
|
|
enable_dampener: bool,
|
|
|
|
dampen_count: i32,
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
|
|
|
|
|
|
// IMPL Report
|
|
|
|
|
|
|
|
//|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
|
|
impl Report
|
|
|
|
impl Report
|
|
|
|
{
|
|
|
|
{
|
|
|
|
pub fn new(lvls: Vec<i32>, enable_dampener: bool) -> Report
|
|
|
|
pub fn new(lvls: Vec<i32>, enable_dampener: bool) -> Report
|
|
|
|
{
|
|
|
|
{
|
|
|
|
Report { levels: lvls , status: Status::Unknown, enable_dampener, dampen_count: 0 }
|
|
|
|
Report { levels: lvls , status: Status::Unknown, enable_dampener }
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// SAFTY RULES:
|
|
|
|
|
|
|
|
// The levels are either all increasing or all decreasing.
|
|
|
|
|
|
|
|
// Any two adjacent levels differ by at least one and at most three.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
pub fn analyze(self: &mut Report, enable_debug_prints: bool) -> Status
|
|
|
|
pub fn analyze(self: &mut Report, enable_debug_prints: bool) -> Status
|
|
|
|
{
|
|
|
|
{
|
|
|
|
let mut prev_direction = 0;
|
|
|
|
if self.enable_dampener
|
|
|
|
let mut i = 0;
|
|
|
|
|
|
|
|
while i < self.levels.len() - 1 // Don't process the last level value
|
|
|
|
|
|
|
|
{
|
|
|
|
{
|
|
|
|
let diff = self.levels[i] - self.levels[i + 1];
|
|
|
|
// Brute force the dampener thing
|
|
|
|
let this_direction = if diff > 0 { 1 } else if diff < 0 { -1 } else { 0 };
|
|
|
|
let mut i = 0;
|
|
|
|
|
|
|
|
let mut status = check_levels(&self.levels, enable_debug_prints);
|
|
|
|
// diff check
|
|
|
|
while i < self.levels.len() && status == Status::Unsafe
|
|
|
|
let diff = diff.abs();
|
|
|
|
|
|
|
|
if diff > 3 || diff < 1
|
|
|
|
|
|
|
|
{
|
|
|
|
{
|
|
|
|
if self.dampen_level(i + 1, enable_debug_prints)
|
|
|
|
let mut levels = self.levels.clone();
|
|
|
|
{
|
|
|
|
levels.remove(i);
|
|
|
|
i = 0;
|
|
|
|
status = check_levels(&levels, enable_debug_prints);
|
|
|
|
continue;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if enable_debug_prints
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
println!("Day 2 DEBUG: Report ({:#?}) is unsafe due to invalid value gap ({}): {} to {}", self.levels, diff, self.levels[i], self.levels[i + 1])
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
self.status = Status::Unsafe;
|
|
|
|
|
|
|
|
return self.status;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// increase/decrease check
|
|
|
|
i += 1;
|
|
|
|
if 0 == prev_direction
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
prev_direction = this_direction
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
else
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
if prev_direction != this_direction
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
if self.dampen_level(i, enable_debug_prints)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
i = 0;
|
|
|
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if enable_debug_prints
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
println!("Day 2 DEBUG: Report ({:#?}) is unsafe due to increase/decrease rule violation: {} to {}", self.levels, self.levels[i], self.levels[i + 1])
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
self.status = Status::Unsafe;
|
|
|
|
|
|
|
|
return self.status;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
self.status = status;
|
|
|
|
i += 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
else
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
self.status = check_levels(&self.levels, enable_debug_prints);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
self.status = Status::Safe;
|
|
|
|
|
|
|
|
return self.status;
|
|
|
|
return self.status;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fn check_levels(self: &mut Report, enable_debug_prints: bool) -> Status
|
|
|
|
fn _try_dampen_level(self: &mut Report, at: usize, do_debug_prints: bool) -> bool
|
|
|
|
{
|
|
|
|
|
|
|
|
Status::Unknown
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
fn dampen_level(self: &mut Report, at: usize, do_debug_prints: bool) -> bool
|
|
|
|
|
|
|
|
{
|
|
|
|
{
|
|
|
|
if !self.enable_dampener
|
|
|
|
if !self.enable_dampener
|
|
|
|
{
|
|
|
|
{
|
|
|
|
@ -105,13 +66,56 @@ impl Report
|
|
|
|
|
|
|
|
|
|
|
|
self.levels.remove(at);
|
|
|
|
self.levels.remove(at);
|
|
|
|
self.enable_dampener = false;
|
|
|
|
self.enable_dampener = false;
|
|
|
|
self.dampen_count += 1;
|
|
|
|
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 };
|
|
|
|
|
|
|
|
|
|
|
|
if self.dampen_count > 1
|
|
|
|
// diff check
|
|
|
|
|
|
|
|
let diff = diff.abs();
|
|
|
|
|
|
|
|
if diff > 3 || diff < 1
|
|
|
|
{
|
|
|
|
{
|
|
|
|
panic!("Day 2 ERROR: Dampener used more than once! usage: {}", self.dampen_count);
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
// 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
|
|
|
|
}
|
|
|
|
}
|