summaryrefslogtreecommitdiffstats
path: root/day2
diff options
context:
space:
mode:
Diffstat (limited to 'day2')
-rw-r--r--day2/Cargo.toml7
-rw-r--r--day2/src/main.rs114
2 files changed, 121 insertions, 0 deletions
diff --git a/day2/Cargo.toml b/day2/Cargo.toml
new file mode 100644
index 0000000..a4354d4
--- /dev/null
+++ b/day2/Cargo.toml
@@ -0,0 +1,7 @@
1[package]
2name = "day2"
3version = "0.1.0"
4edition = "2021"
5
6[dependencies]
7aoc = { path = "../aoc" }
diff --git a/day2/src/main.rs b/day2/src/main.rs
new file mode 100644
index 0000000..15d0224
--- /dev/null
+++ b/day2/src/main.rs
@@ -0,0 +1,114 @@
1use std::io::{BufReader, Read};
2use aoc::Day;
3
4struct Day2{}
5
6impl Day2 {
7 fn part_n(&self, input: BufReader<Box<dyn Read>>) -> Vec<Vec<i32>> {
8 self.read_lines(input)
9 .iter()
10 .map(|l| {
11 l.split_whitespace().map(|c| {
12 c.parse::<i32>().unwrap()
13 })
14 .collect()
15 })
16 .collect()
17 }
18
19 fn is_safe(&self, line: &Vec<i32>) -> Result<bool, usize> {
20 let mut last: Option<&i32> = None;
21 let mut ascending: Option<bool> = None;
22
23 for (index, i) in line.iter().enumerate() {
24 if let Some(l) = last {
25 let abs_diff = l.abs_diff(*i);
26
27
28 if abs_diff < 1 || abs_diff > 3 {
29 return Err(index)
30 }
31
32 if let Some(asc) = ascending {
33 let diff = i - l;
34
35 if (asc && diff < 0) || (!asc && diff > 0) {
36 return Err(index)
37 }
38
39 } else {
40 ascending = Some(i > l);
41 }
42 }
43
44 last = Some(i);
45 }
46
47 Ok(true)
48 }
49}
50
51impl Day for Day2 {
52 fn example_input(&self) -> &'static str {
53 r#"
54 7 6 4 2 1
55 1 2 7 8 9
56 9 7 6 2 1
57 1 3 2 4 5
58 8 6 4 4 1
59 1 3 6 7 9
60 "#.trim()
61 }
62
63 fn example_result_part_1(&self) -> &'static str {
64 "2"
65 }
66
67 fn example_result_part_2(&self) -> &'static str {
68 "4"
69 }
70
71 fn part_1(&self, input: BufReader<Box<dyn Read>>) -> String {
72 self.part_n(input)
73 .iter()
74 .filter(|&l| self.is_safe(l).unwrap_or(false))
75 .count()
76 .to_string()
77 }
78
79 fn part_2(&self, input: BufReader<Box<dyn Read>>) -> String {
80 self.part_n(input)
81 .iter()
82 .filter(|&l| {
83 match self.is_safe(l) {
84 Ok(val) => val,
85 Err(_index) => {
86 l
87 .iter()
88 .enumerate()
89 .map(|(index, _)| {
90 let mut copy = l.clone();
91 copy.remove(index);
92 self.is_safe(&copy).unwrap_or(false)
93 })
94 .any(|val| val)
95 },
96 }
97 })
98 .count()
99 .to_string()
100 }
101}
102
103fn main() {
104 aoc::main(&Day2 {});
105}
106
107#[cfg(test)]
108mod tests {
109 use super::*;
110 #[test]
111 fn test_day2() {
112 aoc::test_day(&Day2 {});
113 }
114}