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(0)); dbg!(&parsed.reflection_score_sum(1)); 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, expected_smudge_count: usize) -> usize { self.0 .iter() .map(|m| m.reflection_score(expected_smudge_count)) .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, expected_smudge_count: usize) -> usize { reflection_i(&self.cols, expected_smudge_count) .or_else(|| reflection_i(&self.rows, expected_smudge_count).map(|y| y * 100)) .expect("No reflection!") } } fn reflection_i(rows: &[String], expected_smudge_count: usize) -> Option { for i in 1..rows.len() { let mut smudge_count = 0; for d in 1..=(i.min(rows.len() - i)) { smudge_count += rows[i - d] .chars() .zip(rows[i + d - 1].chars()) .filter(|(a, b)| a != b) .count(); } let is_reflection = smudge_count == expected_smudge_count; if is_reflection { return Some(i); } } None }