diff --git a/13/src/main.rs b/13/src/main.rs index d380727..b4887e8 100644 --- a/13/src/main.rs +++ b/13/src/main.rs @@ -43,51 +43,75 @@ impl Pattern { } fn find_horizontal_reflection(&self) -> Option { - println!("looking for horiz: {:?}", (1..self.height() - 1).collect::>()); (1..self.height()).find(|idx| self.is_horizontal_reflection(*idx)) } fn is_horizontal_reflection(&self, idx: usize) -> bool { let row_pairs = std::cmp::min(idx, self.height() - idx); - (0..row_pairs).all(|offset| { - println!( - "{}: [{} == {}] {:?} == {:?}", - idx, - idx - offset - 1, - idx + offset, - self.mirrors[idx - offset - 1], - self.mirrors[idx + offset] - ); - self.mirrors[idx - offset - 1] == self.mirrors[idx + offset] - }) + (0..row_pairs).all(|offset| self.mirrors[idx - offset - 1] == self.mirrors[idx + offset]) } fn find_vertical_reflection(&self) -> Option { - println!("looking for vert: {:?}", (1..self.width() - 1).collect::>()); - (1..self.width() ).find(|idx| self.is_vertical_reflection(*idx)) + (1..self.width()).find(|idx| self.is_vertical_reflection(*idx)) } fn is_vertical_reflection(&self, idx: usize) -> bool { let col_pairs = std::cmp::min(idx, self.width() - idx); - (0..col_pairs).all(|offset| { - println!( - "{}: [{} == {}] {:?} == {:?}", - idx, - idx - offset - 1, - idx + offset, - self.col(idx - offset - 1), - self.col(idx + offset) - ); - self.col(idx - offset - 1) == self.col(idx + offset) - }) + (0..col_pairs).all(|offset| self.col(idx - offset - 1) == self.col(idx + offset)) + } + + fn find_smudged_horizontal_reflection(&self) -> Option { + (1..self.height()).find(|idx| self.is_smudged_horizontal_reflection(*idx)) + } + + fn is_smudged_horizontal_reflection(&self, idx: usize) -> bool { + // Same algorithm for problem 2, but count errors breaking reflection. + // If the count == 1 after all checks, then it is our smudge + let row_pairs = std::cmp::min(idx, self.height() - idx); + (0..row_pairs) + .map(|offset| { + self.mirrors[idx - offset - 1] + .iter() + .zip(self.mirrors[idx + offset].iter()) + .filter(|(a, b)| **a != **b) + .count() + }) + .sum::() + == 1 + } + + fn find_smudged_vertical_reflection(&self) -> Option { + (1..self.width()).find(|idx| self.is_smudged_vertical_reflection(*idx)) + } + + fn is_smudged_vertical_reflection(&self, idx: usize) -> bool { + let col_pairs = std::cmp::min(idx, self.width() - idx); + (0..col_pairs) + .map(|offset| { + self.col(idx - offset - 1) + .iter() + .zip(self.col(idx + offset).iter()) + .filter(|(a, b)| **a != **b) + .count() + }) + .sum::() + == 1 } fn reflection_cost(&self) -> u64 { if let Some(refl) = self.find_horizontal_reflection() { - println!("horizontal found at {}", refl); 100 * refl as u64 } else if let Some(refl) = self.find_vertical_reflection() { - println!("vertical found at {}", refl); + refl as u64 + } else { + panic!("no reflection"); + } + } + + fn smudged_reflection_cost(&self) -> u64 { + if let Some(refl) = self.find_smudged_horizontal_reflection() { + 100 * refl as u64 + } else if let Some(refl) = self.find_smudged_vertical_reflection() { refl as u64 } else { panic!("no reflection"); @@ -125,13 +149,19 @@ fn problem1(input: Lines) -> u64 { patterns .patterns .iter() - .map(|pat| { println!("{:?}", pat); pat.reflection_cost() }) + .map(|pat| pat.reflection_cost()) .sum() } // PROBLEM 2 solution fn problem2(input: Lines) -> u64 { - 0 + let patterns = Patterns::from(input); + + patterns + .patterns + .iter() + .map(|pat| pat.smudged_reflection_cost()) + .sum() } #[cfg(test)] @@ -175,9 +205,23 @@ mod tests { assert_eq!(problem1(c.lines()), 405); } + #[test] + fn problem2_find_horizontal() { + let c = Cursor::new(EXAMPLE); + let patterns = Patterns::from(c.lines()); + assert_eq!( + patterns.patterns[0].find_smudged_horizontal_reflection(), + Some(3) + ); + assert_eq!( + patterns.patterns[1].find_smudged_horizontal_reflection(), + Some(1) + ); + } + #[test] fn problem2_example() { let c = Cursor::new(EXAMPLE); - assert_eq!(problem2(c.lines()), 0); + assert_eq!(problem2(c.lines()), 400); } }