Incorrect day 2 part 2 implementation

This commit is contained in:
2025-05-25 19:27:15 -05:00
parent 1510c09b01
commit 45c5a7a1df

View File

@@ -20,19 +20,21 @@ where
Ok(parsed_line) Ok(parsed_line)
} }
#[derive(Eq, PartialEq)] #[derive(Eq, PartialEq, Copy, Clone, Debug)]
enum TransitionState { enum TransitionState {
Good, // Good state Good, // Good state
Bad, // Bad state Bad, // Bad state
Dampened, // Could be removed to make a good state Dampened, // Could be removed to make a good state
DampenedEnd, // Could be removed to make a good state, end or start of report
} }
#[derive(Eq, PartialEq)] #[derive(Eq, PartialEq, Copy, Clone, Debug)]
enum TransitionDirection { enum TransitionDirection {
Asc, // level is increasing Asc, // level is increasing
Desc, // level is decreasing Desc, // level is decreasing
} }
#[derive(Debug)]
struct LevelTransition { struct LevelTransition {
state: TransitionState, state: TransitionState,
direction: TransitionDirection, direction: TransitionDirection,
@@ -94,41 +96,117 @@ fn is_report_safe_no_dampening(report: Vec<i64>) -> bool {
return true; return true;
} }
// fn is_report_safe_with_dampening(report: Vec<i64>) -> bool { fn is_report_safe_with_dampening(report: Vec<i64>) -> bool {
// let mut modified_report: Vec<Option<i64>> = vec![None]; let mut modified_report: Vec<Option<i64>> = vec![None];
// let mut tmp_report: Vec<Option<i64>> = report.iter().map(|v| Some(*v)).collect(); let mut tmp_report: Vec<Option<i64>> = report.iter().map(|v| Some(*v)).collect();
// modified_report.append(&mut tmp_report); modified_report.append(&mut tmp_report);
// modified_report.push(None); modified_report.push(None);
// let states = Vec::new(); let mut transitions = Vec::new();
// for window in modified_report.windows(3) { for window in modified_report.windows(3) {
// let window_tuple = (window[0], window[1], window[2]); let window_tuple = (window[0], window[1], window[2]);
// let state = match window_tuple { let state = match window_tuple {
// (None, Some(curr), Some(next)) | (Some(curr), Some(next), None) => { // We loop through in 3 value windows. We padded a None on
// // Matched first or last element, which means we only have one check to do // either side of the vec to detect the ends of the report for special handling.
// // and we always return Dampened instead of Bad //
// let local_state = compare_levels(curr, next); // If the middle value from the window could be removed to make that section of repo SAFE,
// if local_state == TransitionState::Bad { //mark as Dempened. We will use this later to determine if there's only a single dampened
// // shadow bad with dampened since can always //value we can remove to meet the dampening criteria.
// // remove the first and last element. (None, Some(curr), Some(next)) | (Some(curr), Some(next), None) => {
// TransitionState::Dampened // Matched first or last element, which means we only have one check to do
// } else { // and we always return Dampened instead of Bad
// local_state let local_transition = compare_levels(curr, next);
// } if local_transition.state == TransitionState::Bad {
// }, // shadow bad with dampened since can always
// (Some(prev), Some(curr), Some(next)) => { // remove the first and last element.
// let first_state = compare_levels(prev, curr); LevelTransition {
// let second_state = compare_levels(curr, next); state: TransitionState::DampenedEnd,
// if first_state == TransitionState::Bad || second_state == TransitionState::Bad || first_state != second_state { ..local_transition
}
} else {
local_transition
}
}
(Some(prev), Some(curr), Some(next)) => {
let first_transition = compare_levels(prev, curr);
let second_transition = compare_levels(curr, next);
if first_transition.state != TransitionState::Good
|| second_transition.state != TransitionState::Good
|| first_transition.direction != second_transition.direction
{
let jump_transition = compare_levels(prev, next);
if jump_transition.state == TransitionState::Good {
//println!("Dampening value window: {:?}", window_tuple);
// If we removed the middle value, we would be in a SAFE state, mark as DAMPENED
LevelTransition {
state: TransitionState::Dampened,
..jump_transition
}
} else {
// Removing the middle value does not help us. mark as BAD
LevelTransition {
state: TransitionState::Bad,
..jump_transition
}
}
} else {
// Both transitions are good and moving in the same directions, so we can return either.
second_transition
}
}
_ => panic!("This should never happen!"),
};
transitions.push(state);
}
// } let (mut dampened_cnt, mut prev_direction) = match transitions[0].state {
// }, TransitionState::Good => (0, transitions[0].direction),
// _ => panic!("This should never happen!"), TransitionState::Dampened | TransitionState::DampenedEnd => (1, transitions[1].direction),
// } TransitionState::Bad => {
// states.push(state); panic!("This should never happen!");
// } }
// true };
// } for transition in &transitions {
match transition.state {
TransitionState::Good => {
if transition.direction != prev_direction {
println!(
"Failed for non matching direction: {:?} -> {:?}",
report, transitions
);
return false;
}
}
TransitionState::Dampened => {
dampened_cnt += 1;
if transition.direction != prev_direction {
println!(
"Failed for non matching direction: {:?} -> {:?}",
report, transitions
);
return false;
}
}
TransitionState::DampenedEnd => {
dampened_cnt += 1;
}
TransitionState::Bad => {
// If it's marked as bad we can't fix it by dampening, return false
return false;
}
}
// We can only dampen one value
if dampened_cnt > 1 {
println!(
"Failed for too much dampening: {:?} -> {:?}",
report, transitions
);
return false;
}
prev_direction = transition.direction;
}
true
}
fn main() -> Result<(), Box<dyn Error>> { fn main() -> Result<(), Box<dyn Error>> {
// Handle command input // Handle command input
@@ -145,18 +223,31 @@ fn main() -> Result<(), Box<dyn Error>> {
let input_reader = BufReader::new(input_file); let input_reader = BufReader::new(input_file);
let mut accumulator_no_dampening = 0; let mut accumulator_no_dampening = 0;
let mut accumulator_with_dampening = 0;
for line in input_reader.lines() { for line in input_reader.lines() {
let line = line?; let line = line?;
let parsed_report: Vec<i64> = parse_report(&line)?; let parsed_report: Vec<i64> = parse_report(&line)?;
if is_report_safe_no_dampening(parsed_report) { if is_report_safe_no_dampening(parsed_report.clone()) {
accumulator_no_dampening += 1; accumulator_no_dampening += 1;
} }
if is_report_safe_with_dampening(parsed_report) {
accumulator_with_dampening += 1;
}
} }
println!(
"test: {}",
is_report_safe_with_dampening(vec![1, 3, 2, 4, 5])
);
println!( println!(
"Number of SAFE reports (No Dampening - Part 1): {}", "Number of SAFE reports (No Dampening - Part 1): {}",
accumulator_no_dampening accumulator_no_dampening
); );
println!(
"Number of SAFE reports (With Dampening - Part 2): {}",
accumulator_with_dampening
);
Ok(()) Ok(())
} }