diff --git a/day8/src/main.rs b/day8/src/main.rs index bd4b56e..eb77961 100644 --- a/day8/src/main.rs +++ b/day8/src/main.rs @@ -1,14 +1,13 @@ use std::fs::read_to_string; -use std::collections::HashMap; use num::integer::lcm; -fn get_steps_to(directions: &str, nodes: &HashMap<&str, (&str, &str)>, - start: &str, stop: fn(&str) -> bool) -> u64 { +fn get_steps_to bool>(directions: &str, nodes: &Vec<(u16, u16)>, + start: u16, stop: F) -> u64 { let mut current_node = start; let mut counter: u64 = 0; 'outer: loop { for c in directions.bytes() { - let (left, right) = nodes[current_node]; + let (left, right) = nodes[current_node as usize]; match c { b'L' => current_node = left, b'R' => current_node = right, @@ -23,22 +22,36 @@ fn get_steps_to(directions: &str, nodes: &HashMap<&str, (&str, &str)>, counter } +fn str_to_id(str: &str) -> u16 { + let mut value: u16 = 0; + for c in str.bytes() { + value = value * 26 + (c - b'A') as u16; + } + value +} + fn main() { let lines_str = read_to_string("input.txt").unwrap(); let mut lines_iter = lines_str.lines(); let directions = lines_iter.next().unwrap(); lines_iter.next(); - let nodes = lines_iter.map(|line| { + let mut nodes: Vec<(u16, u16)> = vec![(0, 0); 17576]; + let mut ids_ending_with_a: Vec = Vec::new(); + for line in lines_iter { let mut ids = line.split([' ', '(', ')', '=', ',']).filter(|&str| !str.is_empty()); - (ids.next().unwrap(), (ids.next().unwrap(), ids.next().unwrap())) - }).collect::>(); - let counter1 = get_steps_to(directions, &nodes, "AAA", |str| str == "ZZZ"); - let counter2 = nodes.iter() - .filter_map(|(&id, _)| - Some(id).filter(|&id| id.as_bytes()[2 as usize] == b'A')) - .map(|node| get_steps_to( - directions, &nodes, node, |str| str.as_bytes()[2 as usize] == b'Z')) + let node_id = str_to_id(ids.next().unwrap()); + nodes[node_id as usize] = (str_to_id(ids.next().unwrap()), str_to_id(ids.next().unwrap())); + if node_id % 26 == 0 { + ids_ending_with_a.push(node_id); + } + } + let id_aaa = str_to_id("AAA"); + let id_zzz = str_to_id("ZZZ"); + let counter1 = get_steps_to(directions, &nodes, id_aaa, |id| id == id_zzz); + let counter2 = ids_ending_with_a.iter() + .map(|&node| get_steps_to( + directions, &nodes, node, |id| id % 26 == 25)) .fold(1 as u64, |acc, counter| lcm(acc, counter)); - println!("{}", counter1); - println!("{}", counter2); + println!("Counter1: {}", counter1); + println!("Counter2: {}", counter2); }