use std::collections::HashMap; use std::io::{self, BufRead}; fn diff(left: &str, right: &str) -> Vec<(usize, (char, char))> { left.chars() .zip(right.chars()) .enumerate() .filter(|(_, (a, b))| a != b) .collect::>() } fn main() { let stdin = io::stdin(); let lines = stdin .lock() .lines() .filter_map(Result::ok) .map(|line| { let mut map = HashMap::new(); for ch in line.chars() { map.entry(ch).and_modify(|x| *x += 1).or_insert(1); } (line, map) }).collect::>(); let two = lines .iter() .filter(|(_, map)| map.iter().any(|(_, count)| *count == 2)) .count(); let three = lines .iter() .filter(|(_, map)| map.iter().any(|(_, count)| *count == 3)) .count(); println!("part.one={}", two * three); for (i, (left, _)) in lines.iter().enumerate() { let diff = lines .iter() .skip(i + 1) .map(|(right, _)| diff(left, right)) .find(|diff| diff.len() == 1) .map(|mut diff| diff.pop().unwrap()); if let Some((n, _)) = diff { let string = left .chars() .enumerate() .filter(|(i, _)| *i != n) .map(|(_, c)| c) .collect::(); println!("part.two={:?}", string); break; } } }