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 fn parse_report(line: &str) -> Result, ::Err> where T: FromStr, { let parsed_line = line .split(char::is_whitespace) .map(|v| v.parse()) .collect::, _>>()?; Ok(parsed_line) } enum ReportDirection { Asc, Desc, } fn is_report_safe(report: &Vec) -> 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> { // Handle command input let args: Vec = 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 = parse_report(&line)?; if is_report_safe(&parsed_report) { accumulator += 1; } } println!("Number of SAFE reports: {}", accumulator); Ok(()) }