2025-05-25 16:02:23 -05:00
|
|
|
use std::collections::HashMap;
|
|
|
|
|
use std::env;
|
|
|
|
|
use std::error::Error;
|
|
|
|
|
use std::fs::File;
|
|
|
|
|
use std::io::{BufReader, prelude::*};
|
|
|
|
|
use std::str::FromStr;
|
|
|
|
|
|
|
|
|
|
/// Parse a report into a Vec<T>
|
|
|
|
|
fn parse_report<T>(line: &str) -> Result<Vec<T>, <T as FromStr>::Err>
|
|
|
|
|
where
|
|
|
|
|
T: FromStr,
|
|
|
|
|
{
|
|
|
|
|
let parsed_line = line
|
|
|
|
|
.split(char::is_whitespace)
|
|
|
|
|
.map(|v| v.parse())
|
|
|
|
|
.collect::<Result<Vec<T>, _>>()?;
|
|
|
|
|
Ok(parsed_line)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
enum ReportDirection {
|
|
|
|
|
Asc,
|
|
|
|
|
Desc,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn is_report_safe(report: &Vec<i64>) -> bool {
|
|
|
|
|
let direction = if report[0] < report[1] {
|
|
|
|
|
ReportDirection::Asc
|
|
|
|
|
} else {
|
|
|
|
|
ReportDirection::Desc
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
match direction {
|
|
|
|
|
ReportDirection::Asc => {
|
|
|
|
|
let mut prev_report_level = report[0];
|
|
|
|
|
for report_level in report[1..].iter() {
|
|
|
|
|
if prev_report_level >= *report_level || report_level - prev_report_level > 3 {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
prev_report_level = *report_level;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
ReportDirection::Desc => {
|
|
|
|
|
let mut prev_report_level = report[0];
|
|
|
|
|
for report_level in report[1..].iter() {
|
|
|
|
|
if prev_report_level <= *report_level || prev_report_level - report_level > 3 {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
prev_report_level = *report_level;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
true
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn main() -> Result<(), Box<dyn Error>> {
|
|
|
|
|
// Handle command input
|
|
|
|
|
let args: Vec<String> = env::args().collect();
|
|
|
|
|
if args.len() != 2 {
|
|
|
|
|
panic!(
|
|
|
|
|
"{} must be run with a single argument of files name!",
|
|
|
|
|
&args[0]
|
|
|
|
|
)
|
|
|
|
|
}
|
|
|
|
|
let input_file_string = &args[1];
|
|
|
|
|
|
|
|
|
|
let input_file = File::open(input_file_string)?;
|
|
|
|
|
let input_reader = BufReader::new(input_file);
|
|
|
|
|
|
|
|
|
|
let mut accumulator = 0;
|
|
|
|
|
for line in input_reader.lines() {
|
|
|
|
|
let line = line?;
|
|
|
|
|
let parsed_report: Vec<i64> = parse_report(&line)?;
|
|
|
|
|
if is_report_safe(&parsed_report) {
|
|
|
|
|
accumulator += 1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
println!("Number of SAFE reports: {}", accumulator);
|
|
|
|
|
|
|
|
|
|
Ok(())
|
2025-05-25 13:09:21 -05:00
|
|
|
}
|