From e00b4259ce3c5b546c491a1b6ef66d51237005e0 Mon Sep 17 00:00:00 2001 From: Jens Peters Date: Sat, 9 Dec 2023 07:05:26 +0100 Subject: [PATCH] 2023: Use HashMap --- 2023/src/day08.rs | 56 ++++++++++++++++++++--------------------- 2023/src/util/mod.rs | 2 +- 2023/src/util/string.rs | 2 +- 3 files changed, 30 insertions(+), 30 deletions(-) diff --git a/2023/src/day08.rs b/2023/src/day08.rs index db86864..e7f0dbd 100644 --- a/2023/src/day08.rs +++ b/2023/src/day08.rs @@ -1,7 +1,7 @@ use crate::util::*; +use std::collections::HashMap; struct Element<'a> { - start: &'a str, left: &'a str, right: &'a str, } @@ -11,8 +11,7 @@ fn part01() { let input = read_input(DAYS::Day08); let (instructions, map) = get_instructions_and_elements(&input); - let start = map.iter().find(|e| e.start == "AAA").unwrap(); - let steps = get_steps(start, |e| e == "ZZZ", &instructions, &map); + let steps = get_steps("AAA", |e| e == "ZZZ", &instructions, &map); assert_eq!(steps, 18673); } @@ -24,8 +23,8 @@ fn part02() { let (instructions, map) = get_instructions_and_elements(&input); let steps = map .iter() - .filter(|e| e.start.ends_with('A')) - .map(|e| get_steps(e, |e| e.ends_with('Z'), &instructions, &map)) + .filter(|(k, _)| k.ends_with('A')) + .map(|(k, _)| get_steps(k, |e| e.ends_with('Z'), &instructions, &map)) .collect::>(); let steps = lcm(steps.as_slice()); @@ -34,42 +33,43 @@ fn part02() { } fn get_steps( - start: &Element, - end: fn(start: &str) -> bool, + start_element: &str, + should_end: fn(start: &str) -> bool, instructions: &str, - map: &Vec, + map: &HashMap<&str, Element>, ) -> usize { let mut steps = 0; - let mut current_instruction = 0; - let mut current_element = start; - while !end(current_element.start) { - current_element = map - .iter() - .find(|e| { - if instructions.chars().nth(current_instruction).unwrap() == 'L' { - e.start == current_element.left - } else { - e.start == current_element.right - } - }) - .unwrap(); - current_instruction = (current_instruction + 1) % instructions.len(); + let mut instruction_index = 0; + let mut current_element = start_element; + while !should_end(current_element) { + let element = map.get(current_element).unwrap(); + current_element = if ansi_char_at(instructions, instruction_index) == 'L' { + element.left + } else { + element.right + }; + + instruction_index = (instruction_index + 1) % instructions.len(); steps = steps + 1 } steps } -fn get_instructions_and_elements(input: &str) -> (&str, Vec) { +fn get_instructions_and_elements(input: &str) -> (&str, HashMap<&str, Element>) { let instructions = input.lines().nth(0).unwrap(); let map = input .lines() .skip(2) - .map(|line| Element { - start: &line[0..3], - left: &line[7..10], - right: &line[12..15], + .map(|line| { + ( + &line[0..3], + Element { + left: &line[7..10], + right: &line[12..15], + }, + ) }) - .collect::>(); + .collect::>(); (instructions, map) } diff --git a/2023/src/util/mod.rs b/2023/src/util/mod.rs index fce438e..04ca914 100644 --- a/2023/src/util/mod.rs +++ b/2023/src/util/mod.rs @@ -6,5 +6,5 @@ mod string; pub use days::DAYS; pub use input::read_input; pub use math::lcm; -pub use string::char_at; +pub use string::ansi_char_at; pub use string::char_count; diff --git a/2023/src/util/string.rs b/2023/src/util/string.rs index 7e00798..a061e15 100644 --- a/2023/src/util/string.rs +++ b/2023/src/util/string.rs @@ -1,7 +1,7 @@ use std::collections::HashMap; #[inline(always)] -pub fn char_at(str: &str, index: usize) -> char { +pub fn ansi_char_at(str: &str, index: usize) -> char { // Not a good idea for all kinds of strings. *(&str[index..index + 1].chars().nth(0).unwrap()) }