use nom::{ character::complete::{line_ending, one_of}, combinator::map, multi::{many1, separated_list1}, sequence::pair, IResult, }; use std::fs; fn main() -> Result<(), Box> { let input = fs::read_to_string("inputs/day_13.txt")?; let parsed = ManyMaps::parser(&input).unwrap().1; dbg!(&parsed.reflection_score_sum()); Ok(()) } #[derive(Debug)] struct ManyMaps(Vec); #[derive(Debug)] struct Map { rows: Vec, cols: Vec, } impl ManyMaps { fn parser(input: &str) -> IResult<&str, Self> { map( separated_list1(pair(line_ending, line_ending), Map::parser), ManyMaps, )(input) } fn reflection_score_sum(&self) -> usize { self.0.iter().map(|m| m.reflection_score()).sum() } } impl Map { fn parser(input: &str) -> IResult<&str, Self> { map(separated_list1(line_ending, many1(one_of(".#"))), |rows| { Map { rows: rows .iter() .map(|char_array| char_array.iter().collect::()) .collect(), cols: (0..rows[0].len()) .map(|i| rows.iter().map(|row| row[i]).collect::()) .collect(), } })(input) } fn reflection_score(&self) -> usize { reflection_i(&self.cols) .or_else(|| reflection_i(&self.rows).map(|y| y * 100)) .expect("No reflection!") } } fn reflection_i(rows: &[String]) -> Option { for i in 1..rows.len() { let mut is_reflection = true; let mut d = 1; while is_reflection && d <= i && d + i - 1 < rows.len() { if rows[i - d] != rows[i + d - 1] { is_reflection = false; } d += 1; } if is_reflection { return Some(i); } } None }