blob: 15d0224bc01729373c89a3a72598b5680e03de59 (
plain)
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
109
110
111
112
113
114
|
use std::io::{BufReader, Read};
use aoc::Day;
struct Day2{}
impl Day2 {
fn part_n(&self, input: BufReader<Box<dyn Read>>) -> Vec<Vec<i32>> {
self.read_lines(input)
.iter()
.map(|l| {
l.split_whitespace().map(|c| {
c.parse::<i32>().unwrap()
})
.collect()
})
.collect()
}
fn is_safe(&self, line: &Vec<i32>) -> Result<bool, usize> {
let mut last: Option<&i32> = None;
let mut ascending: Option<bool> = None;
for (index, i) in line.iter().enumerate() {
if let Some(l) = last {
let abs_diff = l.abs_diff(*i);
if abs_diff < 1 || abs_diff > 3 {
return Err(index)
}
if let Some(asc) = ascending {
let diff = i - l;
if (asc && diff < 0) || (!asc && diff > 0) {
return Err(index)
}
} else {
ascending = Some(i > l);
}
}
last = Some(i);
}
Ok(true)
}
}
impl Day for Day2 {
fn example_input(&self) -> &'static str {
r#"
7 6 4 2 1
1 2 7 8 9
9 7 6 2 1
1 3 2 4 5
8 6 4 4 1
1 3 6 7 9
"#.trim()
}
fn example_result_part_1(&self) -> &'static str {
"2"
}
fn example_result_part_2(&self) -> &'static str {
"4"
}
fn part_1(&self, input: BufReader<Box<dyn Read>>) -> String {
self.part_n(input)
.iter()
.filter(|&l| self.is_safe(l).unwrap_or(false))
.count()
.to_string()
}
fn part_2(&self, input: BufReader<Box<dyn Read>>) -> String {
self.part_n(input)
.iter()
.filter(|&l| {
match self.is_safe(l) {
Ok(val) => val,
Err(_index) => {
l
.iter()
.enumerate()
.map(|(index, _)| {
let mut copy = l.clone();
copy.remove(index);
self.is_safe(©).unwrap_or(false)
})
.any(|val| val)
},
}
})
.count()
.to_string()
}
}
fn main() {
aoc::main(&Day2 {});
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_day2() {
aoc::test_day(&Day2 {});
}
}
|