summaryrefslogtreecommitdiff
path: root/2023/src/bin/day_13.rs
diff options
context:
space:
mode:
Diffstat (limited to '2023/src/bin/day_13.rs')
-rw-r--r--2023/src/bin/day_13.rs82
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
+}