1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
|
static DAY: u8 = 13;
fn main() {
let input = advent::read_lines(DAY);
println!("{DAY}a: {}", summarize_patterns(&input));
println!("{DAY}b: {}", 0);
}
#[derive(Clone,Copy)]
enum Reflection {
Vertical(usize),
Horizontal(usize),
}
impl Reflection {
fn summary(&self) -> usize {
match *self {
Reflection::Vertical(column) => column,
Reflection::Horizontal(row) => row * 100,
}
}
}
struct Map {
pattern: Vec<Vec<bool>>,
}
impl Map {
fn new(input: &[String]) -> Map {
let mut pattern = Vec::new();
for line in input {
let row = line.chars()
.map(|c| c == '#')
.collect();
pattern.push(row);
}
Map { pattern }
}
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] {
return false;
}
}
true
}
fn is_vertical_reflection(&self, x: usize) -> bool {
for pair in (x+1 .. self.pattern[0].len()).zip((0 ..= x).rev()) {
for y in 0 .. self.pattern.len() {
if self.pattern[y][pair.0] != self.pattern[y][pair.1] {
return false;
}
}
}
true
}
fn find_reflection(&self) -> Reflection {
for y in 0 .. self.pattern.len() - 1 {
if self.is_horizontal_reflection(y) {
return Reflection::Horizontal(y+1)
}
}
for x in 0 .. self.pattern[0].len() - 1 {
if self.is_vertical_reflection(x) {
return Reflection::Vertical(x+1)
}
}
panic!("no reflection found");
}
}
fn summarize_patterns(input: &[String]) -> usize {
input.split(|line| line.is_empty())
.map(Map::new)
.map(|m| m.find_reflection().summary())
.sum()
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test() {
let input = [
"#.##..##.",
"..#.##.#.",
"##......#",
"##......#",
"..#.##.#.",
"..##..##.",
"#.#.##.#.",
"",
"#...##..#",
"#....#..#",
"..##..###",
"#####.##.",
"#####.##.",
"..##..###",
"#....#..#",
].iter().map(|&x| String::from(x)).collect::<Vec<_>>();
assert_eq!(summarize_patterns(&input), 405);
}
}
|