star three

This commit is contained in:
2024-12-02 18:54:14 -05:00
parent 2c55990d69
commit 1b0a631faa
3 changed files with 131 additions and 0 deletions

1
.gitignore vendored
View File

@@ -1,2 +1,3 @@
/target
/inputs
/.vscode

View File

@@ -2,12 +2,14 @@ use std::env;
mod star_one;
mod star_two;
mod star_three;
fn main() {
let args: Vec<String> = env::args().collect();
match args[1].as_str() {
"1" => star_one::run(),
"2" => star_two::run(),
"3" => star_three::run(),
_ => unreachable!(),
}
}

128
src/star_three.rs Normal file
View File

@@ -0,0 +1,128 @@
use std::fs;
pub fn run() {
let file = fs::read_to_string("./inputs/star_three.txt").unwrap();
let input = file.lines();
let reports = parse_input(input);
let result = count_safe_reports(reports);
println!("Result: {}", result);
}
fn parse_input<'a, I>(str_lines: I) -> Vec<Vec<isize>>
where
I: IntoIterator<Item = &'a str>
{
let mut reports = vec![];
for str_line in str_lines {
let parsed_elems: Vec<isize> = str_line.split_whitespace().map(|n| n.to_string().parse::<isize>().unwrap()).collect();
reports.push(parsed_elems)
}
reports
}
fn count_safe_reports(reports: Vec<Vec<isize>>) -> usize {
reports.iter().filter(|&report| is_level_change_safe(report)).count()
}
#[derive(PartialEq, Copy, Clone)]
enum Balancing {
Increasing,
Decreasing,
}
fn is_level_change_safe(report: &Vec<isize>) -> bool {
if report.len() < 2 {
return false;
}
let mut i = 1;
let mut last_balancing = None;
while i < report.len() {
let prev_level = report[i - 1];
let current_level = report[i];
if prev_level == current_level {
return false;
}
let difference = match current_level > prev_level {
true => current_level - prev_level,
false => prev_level - current_level,
};
if difference > 3 {
return false;
}
if let Some(current_balancing) = last_balancing {
let new_balancing = match current_level > prev_level {
true => Balancing::Increasing,
false => Balancing::Decreasing,
};
if new_balancing != current_balancing {
return false;
}
} else {
last_balancing = match current_level > prev_level {
true => Some(Balancing::Increasing),
false => Some(Balancing::Decreasing),
}
}
i += 1;
}
true
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_parse_input() {
let input = vec![
"7 6 4 2 1",
"1 2 7 8 9",
"9 7 6 2 1",
"1 3 2 4 5",
"8 6 4 4 1",
"1 3 6 7 9",
];
let result = parse_input(input);
let expected_result = vec![
vec![7, 6, 4, 2, 1],
vec![1, 2, 7, 8, 9],
vec![9, 7, 6, 2, 1],
vec![1, 3, 2, 4, 5],
vec![8, 6, 4, 4, 1],
vec![1, 3, 6, 7, 9],
];
assert_eq!(result, expected_result);
}
#[test]
fn test_count_safe_reports() {
let reports = vec![
vec![7, 6, 4, 2, 1],
vec![1, 2, 7, 8, 9],
vec![9, 7, 6, 2, 1],
vec![1, 3, 2, 4, 5],
vec![8, 6, 4, 4, 1],
vec![1, 3, 6, 7, 9],
];
assert_eq!(count_safe_reports(reports), 2);
}
#[test]
fn test_is_level_change_safe() {
assert!(is_level_change_safe(&vec![7, 6, 4, 2, 1]));
assert!(!is_level_change_safe(&vec![1, 2, 7, 8, 9]));
assert!(!is_level_change_safe(&vec![9, 7, 6, 2, 1]));
assert!(!is_level_change_safe(&vec![1, 3, 2, 4, 5]));
assert!(!is_level_change_safe(&vec![8, 6, 4, 4, 1]));
assert!(is_level_change_safe(&vec![1, 3, 6, 7, 9]));
}
}