use num::integer::lcm; use std::collections::HashMap; use std::fs::File; use std::io::Read; fn main() { // let filename = "in/day08.ref"; let filename = "in/day08.pzl"; let mut f = File::open(filename).expect("cannot open file"); let mut content = String::new(); f.read_to_string(&mut content).expect("cannot read file"); let mut lines = content.trim_end().split("\n\n"); let ops: Vec = lines.next().unwrap().chars().collect(); let mut tree: HashMap<&str, (&str, &str)> = HashMap::new(); for line in lines.next().unwrap().split('\n') { let (first, rest) = line.split_once(" = ").unwrap(); let (left, right) = rest.split_once(", ").unwrap(); let left = &left[1..]; let right = &right[..3]; tree.insert(first, (left, right)); } let traverse_tree_until = |start: &str, f: fn(&str) -> bool| { let mut loc = start; let mut steps: usize = 0; loop { let (left, right) = tree.get(loc).unwrap(); let op = ops[steps % ops.len()]; if op == 'L' { loc = left; } else { loc = right; } if f(&loc) { break; } steps += 1; } (steps + 1) as u64 }; let res1 = traverse_tree_until("AAA", |x| x == "ZZZ"); let locs = tree.keys().filter(|x| &x[2..3] == "A").collect::>(); let mut stps: Vec = Vec::new(); for i in 0..locs.len() { stps.push(traverse_tree_until(locs[i], |x| x.ends_with("Z"))); } let res2 = stps.iter().fold(1, |x, y| lcm(x, *y)); println!("res1: {}", res1); println!("res2: {}", res2); assert_eq!(res1, 14257); assert_eq!(res2, 16187743689077); }