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::>(); 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::>(); // let start_nodes = map.keys().into_iter().filter(|x| x.chars().last().unwrap() == 'A').collect::>(); // 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::>(); let start_nodes = map.keys().into_iter().filter(|x| x.chars().last().unwrap() == 'A').collect::>(); let mut solutions = Vec::::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; }