Files
advent-of-code-2023/day_08/src/lib.rs
2023-12-07 23:51:02 -07:00

73 lines
2.3 KiB
Rust

use nom::{
bytes::complete::{take_until, take, tag},
character::complete::{
newline, multispace1, alphanumeric1,
},
sequence::{preceded, separated_pair},
multi::separated_list1,
IResult,
};
use std::collections::HashMap;
use std::str::Chars;
fn parse_mapline(input: &str) -> IResult<&str, (&str, (&str, &str))> {
let (input, start) = take(3 as usize)(input)?;
let (input, (left, right)) = preceded(tag(" = ("), separated_pair(alphanumeric1, tag(", "), alphanumeric1))(input)?;
Ok((input, (start, (left, right))))
}
pub fn part1(input: &str) -> String {
let mut lines = input.lines();
let instructions = lines.next().unwrap().chars();
let map = lines.skip(1).map(|line| {
parse_mapline(line).unwrap().1
}).collect::<HashMap<&str, (&str, &str)>>();
let mut total_steps = 0;
let mut position = "AAA";
for _ in 0..100 {
for instruction in instructions.clone() {
total_steps += 1;
let (left, right) = map.get(position).unwrap();
if instruction == 'L' {
position = left;
} else {
position = right;
}
if position == "ZZZ" { return total_steps.to_string(); };
}
};
total_steps.to_string()
}
pub fn part2(input: &str) -> String {
let mut lines = input.lines();
let instructions = lines.next().unwrap().chars();
let map = lines.skip(1).map(|line| {
parse_mapline(line).unwrap().1
}).collect::<HashMap<&str, (&str, &str)>>();
let start_nodes = map.keys().into_iter().filter(|x| x.chars().last().unwrap() == 'A').collect::<Vec<_>>();
let mut total_steps = 0;
let mut positions = start_nodes;
for _ in 0..10000000 {
for instruction in instructions.clone() {
total_steps += 1;
for i in 0..positions.len() {
let (left, right) = map.get(positions[i]).unwrap();
if instruction == 'L' {
positions[i] = &left;
} else {
positions[i] = &right;
}
}
if positions.iter().all(|x| {x.chars().last().unwrap() == 'Z'}) { return total_steps.to_string(); };
}
};
total_steps.to_string()
}
pub mod prelude {
pub use super::part1;
pub use super::part2;
}