diff --git a/src/advent_of_code/mon_02.rs b/src/advent_of_code/mon_02.rs index 10b04e3..e26bc01 100644 --- a/src/advent_of_code/mon_02.rs +++ b/src/advent_of_code/mon_02.rs @@ -9,36 +9,12 @@ pub fn check_reports_safety(input: &str) -> ReportSafety { // 1. All levels must be all increasing or decreasing // 2. All levels must change by at leat one and at most three - for report in report_list { if report.len() < 2 { - safe_count += 1; break; } - let mut safe = true; - let initial_direction: ReportDirection = get_report_direction(&report[0..=1]); - let mut problems_damped_count = 0; - - 'report_check: for index in 1..report.len() { - let prev = index - 1; - let distance = calc_distance(report[index], report[prev]); - let direction = get_report_direction(&[report[prev], report[index]]); - - if report[index] == report[prev] - || distance < 1 - || distance > 3 - || direction != initial_direction - { - if report_problem_dampener(&report) == false { - safe = false; - break 'report_check; - } - problems_damped_count += 1; - } - } - - if safe { + if is_report_safe(&report, true) { safe_count += 1; } } @@ -46,11 +22,45 @@ pub fn check_reports_safety(input: &str) -> ReportSafety { safe_count } -// NOTE: the simples solition is by brute force... -fn report_problem_dampener(report: &Vec) -> bool {} +fn is_report_safe(report: &Report, apply_problem_dampener: bool) -> bool { + if report.len() < 2 { + return false; + } + let mut safe = true; + let initial_direction: ReportDirection = get_report_direction(&report[0..=1]); + + 'report_check: for index in 1..report.len() { + if !is_level_pair_valid(&report[index - 1], &report[index], &initial_direction) { + if apply_problem_dampener { + let sliced_index_report = + [&report[0..index], &report[index + 1..report.len()]].concat(); + if is_report_safe(&sliced_index_report, false) { + break 'report_check; + } else { + let sliced_prev_report = + [&report[0..index - 1], &report[index..report.len()]].concat(); + if is_report_safe(&sliced_prev_report, false) { + break 'report_check; + } + } + } + safe = false; + break 'report_check; + } + } + + safe +} + +fn is_level_pair_valid(first: &Level, second: &Level, initial_direction: &ReportDirection) -> bool { + let distance = calc_distance(*second, *first); + let direction = get_report_direction(&[*first, *second]); + + !(first == second || distance < 1 || distance > 3 || direction != *initial_direction) +} // FIXME: this is not a good function, since may try to access an invalid index -fn get_report_direction(report: &[Report]) -> ReportDirection { +fn get_report_direction(report: &[Level]) -> ReportDirection { if report[1] - report[0] > 0 { ReportDirection::Increasing } else { diff --git a/src/advent_of_code/types.rs b/src/advent_of_code/types.rs index 55ecfed..4491ac7 100644 --- a/src/advent_of_code/types.rs +++ b/src/advent_of_code/types.rs @@ -2,7 +2,8 @@ pub type Id = i32; pub type Key = Id; pub type Similarity = Id; -pub type Report = i32; +pub type Level = i32; +pub type Report = Vec; pub type ReportSafety = u32; #[derive(Debug, PartialEq, Eq)] diff --git a/src/advent_of_code/utils.rs b/src/advent_of_code/utils.rs index 72bf134..710e475 100644 --- a/src/advent_of_code/utils.rs +++ b/src/advent_of_code/utils.rs @@ -17,14 +17,14 @@ pub fn read_id_lists(input: &str) -> (Vec, Vec) { return (list_1, list_2); } -pub fn read_report_list(input: &str) -> Vec> { - let mut report_list: Vec> = vec![]; +pub fn read_report_list(input: &str) -> Vec { + let mut report_list: Vec = vec![]; for report in read_to_string(input).unwrap().lines() { let level_list = report.split(" "); - let mut report_vec: Vec = vec![]; + let mut report_vec: Report = vec![]; for level in level_list { - report_vec.push(level.parse::().unwrap()); + report_vec.push(level.parse::().unwrap()); } report_list.push(report_vec); }