diff --git a/src/08part1.rs b/src/08part1.rs new file mode 100644 index 0000000..ce5396f --- /dev/null +++ b/src/08part1.rs @@ -0,0 +1,37 @@ +use std::{fs, collections::HashMap}; + +#[derive(Debug)] +struct Node { + left: String, + right: String, +} + +fn main() { + let file_path = "input/08input.txt"; + let contents = fs::read_to_string(file_path).expect("should read file"); + let mut lines = contents.lines(); + let instructions: Vec = lines.next().unwrap().chars().collect(); + let mut node_map = HashMap::new(); + lines.next(); + loop { + let line = lines.next(); + if line.is_none() { + break; + } + let line_components = line.unwrap().split_at(4); + let lhs = line_components.0.get(0..3); + let rhs = line_components.1.split_at(7); + node_map.insert(lhs.unwrap(), Node{left: rhs.0.get(3..6).unwrap().to_owned(), right: rhs.1.get(1..4).unwrap().to_owned()}); + } + let mut current_node = "AAA"; + let mut count = 0; + while current_node != "ZZZ" { + if instructions[count % instructions.len()] == 'L' { + current_node = &node_map[current_node].left; + } else { + current_node = &node_map[current_node].right; + } + count += 1; + } + println!("{}", count); +} diff --git a/src/08part2.rs b/src/08part2.rs new file mode 100644 index 0000000..4e4775e --- /dev/null +++ b/src/08part2.rs @@ -0,0 +1,93 @@ +use std::{fs, collections::HashMap}; + +struct Node { + left: String, + right: String, +} + +#[derive(Eq, Hash, Debug)] +struct NodeInstruction { + node: String, + instruction: usize, +} + +impl PartialEq for NodeInstruction { + fn eq(&self, other: &Self) -> bool { + return self.node == other.node && self.instruction == other.instruction; + } +} + +fn main() { + let file_path = "input/08input.txt"; + let contents = fs::read_to_string(file_path).expect("should read file"); + let mut lines = contents.lines(); + let instructions: Vec = lines.next().unwrap().chars().collect(); + let mut nodes: HashMap = HashMap::new(); + lines.next(); + let mut current_nodes = Vec::new(); + loop { + let line = lines.next(); + if line.is_none() { + break; + } + let line_components = line.unwrap().split_at(4); + let lhs = line_components.0.get(0..3); + if lhs.unwrap().chars().collect::>()[2] == 'A' { + current_nodes.push(lhs.unwrap().to_string()); + } + let rhs = line_components.1.split_at(7); + let rhs_left = rhs.0.get(3..6).unwrap(); + let rhs_right = rhs.1.get(1..4).unwrap(); + nodes.insert(lhs.unwrap().to_string(), Node {left: rhs_left.to_string(), right: rhs_right.to_string()}); + } + let mut count = 0; + let mut cycles: Vec = Vec::new(); + println!("{}", current_nodes.len()); + loop { + if current_nodes.len() == 0 { + break; + } + if current_nodes[0].chars().collect::>()[2] == 'Z' { + cycles.push(count); + current_nodes.remove(0); + count = 0; + } else { + if instructions[count % instructions.len()] == 'L'{ + current_nodes[0] = nodes[¤t_nodes[0]].left.to_owned(); + } else { + current_nodes[0] = nodes[¤t_nodes[0]].right.to_owned(); + } + count += 1; + } + } + while cycles.len() > 1 { + let a = cycles.pop().unwrap(); + let b = cycles.pop().unwrap(); + cycles.push(lcm(a, b)); + } + println!("{}", cycles[0]); +} + +fn lcm(first: usize, second: usize) -> usize { + first * second / gcd(first, second) +} + +fn gcd(first: usize, second: usize) -> usize { + let mut max = first; + let mut min = second; + if min > max { + let val = max; + max = min; + min = val; + } + + loop { + let res = max % min; + if res == 0 { + return min; + } + + max = min; + min = res; + } +}