Files
advent-of-code-2023/day_08/src/lib.rs
2023-12-08 00:21:19 -07:00

100 lines
3.5 KiB
Rust

use nom::{
bytes::complete::{take, tag},
character::complete::alphanumeric1,
sequence::{preceded, separated_pair},
IResult,
};
use std::collections::HashMap;
use num::integer::lcm;
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_u64;
// let mut positions = start_nodes;
// for _ in 0..1000000 {
// 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()
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 solutions = Vec::<u64>::new();
for ind in 0..start_nodes.len() {
let mut total_steps = 0;
let start_node = start_nodes[ind];
let mut position = *start_node;
for _ in 0..100000 {
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.chars().last().unwrap() == 'Z' { break; };
}
if position.chars().last().unwrap() == 'Z' { break; };
};
solutions.push(total_steps);
}
println!("{:?}", &solutions);
let first = solutions[0];
solutions.into_iter().skip(1).fold(first, |acc, x| {lcm(acc, x)}).to_string()
}
pub mod prelude {
pub use super::part1;
pub use super::part2;
}