use std::collections::{HashMap, HashSet}; fn main() { let input = advent::read_lines(19); println!("19a: {}", distinct_molecules(&input)); println!("19b: {}", 0); } fn distinct_molecules(input: &[String]) -> usize { let mut input = input.to_owned(); let molecule = input.pop().unwrap(); input.pop(); // drop empty line let mut replacements = HashMap::new(); for line in input { let replacement : Vec<_> = line.split(" => ").collect(); let (left, right) = (replacement[0].to_string(), replacement[1].to_string()); replacements.entry(left).or_insert(Vec::new()).push(right); } let mut result = HashSet::new(); for (left, rights) in replacements { for right in rights { for i in 0 .. molecule.len() { let check_pos = std::cmp::min(i + left.len(), molecule.len()); if molecule[i..check_pos].contains(&left) { let new_molecule = molecule[0..i].to_string() + &right + &molecule[(i + left.len())..]; result.insert(new_molecule); } } } } result.len() } #[cfg(test)] mod tests { use super::*; #[test] fn test() { let mut input = Vec::from([ "H => HO".to_string(), "H => OH".to_string(), "O => HH".to_string(), "".to_string(), "HOH".to_string(), ]); assert_eq!(distinct_molecules(&input), 4); input.pop(); input.push("HOHOHO".to_string()); assert_eq!(distinct_molecules(&input), 7); } }