summaryrefslogtreecommitdiff
path: root/src/bin/day13.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/bin/day13.rs')
-rw-r--r--src/bin/day13.rs58
1 files changed, 50 insertions, 8 deletions
diff --git a/src/bin/day13.rs b/src/bin/day13.rs
index 6f6ac97..02045ea 100644
--- a/src/bin/day13.rs
+++ b/src/bin/day13.rs
@@ -1,12 +1,14 @@
+use std::collections::HashSet;
+
static DAY: u8 = 13;
fn main() {
let input = advent::read_lines(DAY);
println!("{DAY}a: {}", summarize_patterns(&input));
- println!("{DAY}b: {}", 0);
+ println!("{DAY}b: {}", summarize_patterns_with_smudge(&input));
}
-#[derive(Clone,Copy)]
+#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash)]
enum Reflection {
Vertical(usize),
Horizontal(usize),
@@ -15,12 +17,13 @@ enum Reflection {
impl Reflection {
fn summary(&self) -> usize {
match *self {
- Reflection::Vertical(column) => column,
- Reflection::Horizontal(row) => row * 100,
+ Reflection::Vertical(column) => column + 1,
+ Reflection::Horizontal(row) => (row + 1) * 100,
}
}
}
+#[derive(Clone)]
struct Map {
pattern: Vec<Vec<bool>>,
}
@@ -38,6 +41,20 @@ impl Map {
Map { pattern }
}
+ fn _print_map(&self) {
+ for y in 0 .. self.pattern.len() {
+ for x in 0 .. self.pattern[0].len() {
+ if self.pattern[y][x] {
+ print!("#");
+ } else {
+ print!(".");
+ }
+ }
+ println!();
+ }
+ println!();
+ }
+
fn is_horizontal_reflection(&self, y: usize) -> bool {
for pair in (y+1 .. self.pattern.len()).zip((0 ..= y).rev()) {
if self.pattern[pair.0] != self.pattern[pair.1] {
@@ -58,17 +75,34 @@ impl Map {
true
}
- fn find_reflection(&self) -> Reflection {
+ fn find_reflections(&self) -> HashSet<Reflection> {
+ let mut reflections = HashSet::new();
for y in 0 .. self.pattern.len() - 1 {
if self.is_horizontal_reflection(y) {
- return Reflection::Horizontal(y+1)
+ reflections.insert(Reflection::Horizontal(y));
}
}
for x in 0 .. self.pattern[0].len() - 1 {
if self.is_vertical_reflection(x) {
- return Reflection::Vertical(x+1)
+ reflections.insert(Reflection::Vertical(x));
}
}
+ reflections
+ }
+
+ fn find_reflection_with_smudge(&self) -> Reflection {
+ let orig_reflection = self.find_reflections();
+ for y in 0 .. self.pattern.len() {
+ for x in 0 .. self.pattern[0].len() {
+ let mut map = self.clone();
+ map.pattern[y][x] = !map.pattern[y][x];
+ let reflections = map.find_reflections();
+ let new_reflections = reflections.difference(&orig_reflection).collect::<Vec<_>>();
+ if !new_reflections.is_empty() {
+ return *new_reflections[0];
+ }
+ }
+ }
panic!("no reflection found");
}
}
@@ -76,7 +110,14 @@ impl Map {
fn summarize_patterns(input: &[String]) -> usize {
input.split(|line| line.is_empty())
.map(Map::new)
- .map(|m| m.find_reflection().summary())
+ .map(|m| m.find_reflections().iter().next().unwrap().summary())
+ .sum()
+}
+
+fn summarize_patterns_with_smudge(input: &[String]) -> usize {
+ input.split(|line| line.is_empty())
+ .map(Map::new)
+ .map(|m| m.find_reflection_with_smudge().summary())
.sum()
}
@@ -104,5 +145,6 @@ mod tests {
"#....#..#",
].iter().map(|&x| String::from(x)).collect::<Vec<_>>();
assert_eq!(summarize_patterns(&input), 405);
+ assert_eq!(summarize_patterns_with_smudge(&input), 400);
}
}