use std::collections::HashMap; use std::fs; fn solve_puzzle(lines: &Vec<&str>, use_max: bool) -> String { let mut freqs = Vec::new(); for _i in 0..lines[0].len() { let hm: HashMap = HashMap::new(); freqs.push(hm); } // Count char occurrences at each index in line for line in lines { for (i, c) in line.chars().enumerate() { *freqs[i].entry(c).or_insert(0) += 1; } } let mut result = String::new(); for hm in freqs { let c = if use_max { // Part 1: take most common character hm.into_iter().max_by_key(|x| x.1).unwrap().0 } else { // Part 2: take least common character hm.into_iter().min_by_key(|x| x.1).unwrap().0 }; result.push(c); } result } fn main() { // Read messages from input text file let input = fs::read_to_string("input.txt").unwrap(); let lines = input.lines().collect(); // Part 1 gives "mlncjgdg" for me println!("Part 1 solution: {}", solve_puzzle(&lines, true)); // Part 2 gives "bipjaytb" for me println!("Part 2 solution: {}", solve_puzzle(&lines, false)); } #[cfg(test)] mod tests { use super::*; const EXAMPLE1_LINES: [&str; 16] = [ "eedadn", "drvtee", "eandsr", "raavrd", "atevrs", "tsrnev", "sdttsa", "rasrtv", "nssdts", "ntnada", "svetve", "tesnvt", "vntsnd", "vrdear", "dvrsen", "enarar", ]; #[test] fn part1_example1() { assert_eq!(solve_puzzle(&Vec::from(EXAMPLE1_LINES), true), "easter"); } #[test] fn part2_example1() { assert_eq!(solve_puzzle(&Vec::from(EXAMPLE1_LINES), false), "advent"); } }