diff options
Diffstat (limited to '2023/src/bin/day_13.rs')
-rw-r--r-- | 2023/src/bin/day_13.rs | 82 |
1 files changed, 82 insertions, 0 deletions
diff --git a/2023/src/bin/day_13.rs b/2023/src/bin/day_13.rs new file mode 100644 index 0000000..ad97602 --- /dev/null +++ b/2023/src/bin/day_13.rs @@ -0,0 +1,82 @@ +use nom::{ + character::complete::{line_ending, one_of}, + combinator::map, + multi::{many1, separated_list1}, + sequence::pair, + IResult, +}; +use std::fs; + +fn main() -> Result<(), Box<dyn std::error::Error>> { + 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<Map>); + +#[derive(Debug)] +struct Map { + rows: Vec<String>, + cols: Vec<String>, +} + +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::<String>()) + .collect(), + cols: (0..rows[0].len()) + .map(|i| rows.iter().map(|row| row[i]).collect::<String>()) + .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<usize> { + 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 +} |