diff options
Diffstat (limited to '2023/day08.rs')
| -rw-r--r-- | 2023/day08.rs | 59 |
1 files changed, 59 insertions, 0 deletions
diff --git a/2023/day08.rs b/2023/day08.rs new file mode 100644 index 0000000..510ddba --- /dev/null +++ b/2023/day08.rs @@ -0,0 +1,59 @@ +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<char> = 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::<Vec<_>>(); + let mut stps: Vec<u64> = 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); +} |
