use { anyhow::{ anyhow, Context, Result, }, std::{ env::args, fs::read_to_string, path::Path, }, }; fn read_input>(filename: T) -> Result { read_to_string(filename).context("Could not read {filename}") } fn find_sequence(input: &str, len: usize) -> Option { input.as_bytes().windows(len).enumerate().find_map(|(pos, win)| { for i in 0..len { if win[(i + 1)..].contains(&win[i]) { return None } } Some(pos + len) }) } fn part1(input: &str) -> Result { find_sequence(input, 4).ok_or_else(|| anyhow!("No match found")) } fn part2(input: &str) -> Result { find_sequence(input, 14).ok_or_else(|| anyhow!("No match found")) } fn main() -> Result<()> { let ( do_part_1, do_part_2 ) = aoc::do_parts(); let filename = args().nth(1).ok_or_else(|| anyhow!("Missing input filename"))?; let input = read_input(filename).context("Could not read input")?; if do_part_1 { let solution = part1(&input).context("No solution for part 1")?; println!("Part1, solution found to be: {}", solution); } if do_part_2 { let solution = part2(&input).context("No solution for part 2")?; println!("Part2, solution found to be: {}", solution); } Ok(()) }