use std::{ fs::File, io::{BufRead, BufReader}, path::Path, }; pub fn solve(input: &Path) -> anyhow::Result<()> { println!("part one: {}", part_one(input)?); println!("part two: {}", part_two(input)?); Ok(()) } fn part_one(input: &Path) -> anyhow::Result { let reader = BufReader::new(File::open(input)?); let mut reports: Vec> = vec![]; for line in reader.lines() { reports.push( line? .split_whitespace() .map(|n| -> i32 { n.parse().unwrap() }) .collect(), ); } let mut safe = 0; for r in reports { let mut s = 0; let mut safes: i32 = 0; let mut last_level = None; for current in &r { if last_level.is_none() { last_level = Some(current); continue; } let last = last_level.unwrap(); let diff = (current - last).abs(); if diff < 4 && diff > 0 { if current > last { safes += 1; } else if current < last { safes -= 1; } if safes.abs() == (r.len() as i32) - 1 { s = 1; } } last_level = Some(current); } safe += s; } Ok(safe) } fn part_two(input: &Path) -> anyhow::Result { let reader = BufReader::new(File::open(input)?); let mut reports: Vec> = vec![]; for line in reader.lines() { reports.push( line? .split_whitespace() .map(|n| -> i32 { n.parse().unwrap() }) .collect(), ); } let mut safe = 0; for r in reports { let mut s = 0; for i in 0..r.len() { let mut a = r.clone(); a.remove(i); if is_safe_two(a) == 1 { s = 1; break; } } safe += s; } Ok(safe) } fn is_safe_two(r: Vec) -> i32 { let mut s = 0; let mut safes: i32 = 0; let mut last_level = None; for current in &r { if last_level.is_none() { last_level = Some(current); continue; } let last = last_level.unwrap(); let diff = (current - last).abs(); if diff < 4 && diff > 0 { if current > last { safes += 1; } else if current < last { safes -= 1; } if safes.abs() == (r.len() as i32) - 1 { s = 1; } } last_level = Some(current); } s }