Skip to content

Commit

Permalink
2023: Use HashMap
Browse files Browse the repository at this point in the history
  • Loading branch information
jp7677 committed Dec 9, 2023
1 parent 321c874 commit e00b425
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 30 deletions.
56 changes: 28 additions & 28 deletions 2023/src/day08.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use crate::util::*;
use std::collections::HashMap;

struct Element<'a> {
start: &'a str,
left: &'a str,
right: &'a str,
}
Expand All @@ -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);
}
Expand All @@ -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::<Vec<usize>>();

let steps = lcm(steps.as_slice());
Expand All @@ -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<Element>,
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<Element>) {
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::<Vec<Element>>();
.collect::<HashMap<&str, Element>>();

(instructions, map)
}
2 changes: 1 addition & 1 deletion 2023/src/util/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
2 changes: 1 addition & 1 deletion 2023/src/util/string.rs
Original file line number Diff line number Diff line change
@@ -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())
}
Expand Down

0 comments on commit e00b425

Please sign in to comment.