use nom::{ branch::alt, character::complete::{char as nom_char, line_ending}, combinator::{map, value}, multi::{many1, separated_list1}, IResult, }; use std::fs; fn main() -> Result<(), Box> { let input = fs::read_to_string("inputs/day_25.txt")?; let mut seafloor = parse_seafloor(&input).unwrap().1; for i in 1.. { let next = seafloor.next(); if next == seafloor { dbg!(i); break; } seafloor = next; } Ok(()) } #[derive(Debug, PartialEq, Eq)] struct Seafloor(Vec>>); impl Seafloor { fn next(&self) -> Seafloor { self.next_east().next_south() } fn next_east(&self) -> Seafloor { let mut results = Vec::new(); for y in 0..self.0.len() { let mut current_row = Vec::new(); for x in 0..self.0[y].len() { let old = &self.0[y][x]; let old_left = &self.0[y][if x == 0 { self.0[y].len() - 1 } else { x - 1 }]; let old_right = &self.0[y][(x + 1) % self.0[y].len()]; let new = if *old == None && *old_left == Some(Cucumber::East) { old_left.clone() } else if *old == Some(Cucumber::East) && *old_right == None { None } else { old.clone() }; current_row.push(new); } results.push(current_row); } Seafloor(results) } fn next_south(&self) -> Seafloor { let mut results = Vec::new(); for y in 0..self.0.len() { let mut current_row = Vec::new(); for x in 0..self.0[y].len() { let old = &self.0[y][x]; let old_up = &self.0[if y == 0 { self.0.len() - 1 } else { y - 1 }][x]; let old_down = &self.0[(y + 1) % self.0.len()][x]; let new = if *old == None && *old_up == Some(Cucumber::South) { old_up.clone() } else if *old == Some(Cucumber::South) && *old_down == None { None } else { old.clone() }; current_row.push(new); } results.push(current_row); } Seafloor(results) } } #[derive(Debug, Clone, PartialEq, Eq)] enum Cucumber { East, South, } fn parse_seafloor(input: &str) -> IResult<&str, Seafloor> { map( separated_list1(line_ending, many1(parse_cucumber)), Seafloor, )(input) } fn parse_cucumber(input: &str) -> IResult<&str, Option> { alt(( value(None, nom_char('.')), value(Some(Cucumber::East), nom_char('>')), value(Some(Cucumber::South), nom_char('v')), ))(input) }