diff options
Diffstat (limited to 'day5/src/main.rs')
-rw-r--r-- | day5/src/main.rs | 136 |
1 files changed, 136 insertions, 0 deletions
diff --git a/day5/src/main.rs b/day5/src/main.rs new file mode 100644 index 0000000..e55b244 --- /dev/null +++ b/day5/src/main.rs | |||
@@ -0,0 +1,136 @@ | |||
1 | use std::fs; | ||
2 | use std::path::Path; | ||
3 | use regex::Regex; | ||
4 | use lazy_static::lazy_static; | ||
5 | |||
6 | #[derive(Debug,PartialEq)] | ||
7 | struct Segment(u32,u32,u32,u32); | ||
8 | |||
9 | impl Segment { | ||
10 | fn is_hor(&self) -> bool { | ||
11 | self.1 == self.3 | ||
12 | } | ||
13 | fn is_ver(&self) -> bool { | ||
14 | self.0 == self.2 | ||
15 | } | ||
16 | } | ||
17 | |||
18 | /* AOC21 Day 7: https://adventofcode.com/2021/day/7 */ | ||
19 | fn main() { | ||
20 | let input = Path::new("resources").join("input.txt"); | ||
21 | let content = fs::read_to_string(input).expect("Unable to read input file"); | ||
22 | let (size, segments) = parse_input(&content); | ||
23 | let area = radar(&segments, size, false); | ||
24 | println!("Ex1: The result is: {}", area.iter().filter(|&&c| c > 1).count()); | ||
25 | let area = radar(&segments, size, true); | ||
26 | println!("Ex2: The result is: {}", area.iter().filter(|&&c| c > 1).count()); | ||
27 | } | ||
28 | |||
29 | fn radar(segments: &[Segment], size: u32, diagonals: bool) -> Vec<u32> { | ||
30 | let mut area = vec![0;(size+1).pow(2) as usize]; | ||
31 | segments.iter().for_each( | ||
32 | |s| match s { | ||
33 | s if s.is_hor() => { | ||
34 | range(s.0, s.2).iter().for_each(|x| area[((size+1)*s.1 + x) as usize] += 1) | ||
35 | }, | ||
36 | s if s.is_ver() => { | ||
37 | range(s.1, s.3).iter().for_each(|y| area[((size+1)*y + s.0) as usize] += 1) | ||
38 | }, | ||
39 | s => { | ||
40 | if diagonals { | ||
41 | range(s.0,s.2).iter().zip(range(s.1,s.3)).for_each(|(x,y)| area[((size+1)*y + x) as usize] += 1) | ||
42 | } | ||
43 | } | ||
44 | } | ||
45 | ); | ||
46 | area | ||
47 | } | ||
48 | |||
49 | fn parse_input(s: &str) -> (u32, Vec<Segment>) { | ||
50 | lazy_static! { | ||
51 | static ref RE: Regex = Regex::new(r"^(\d+),(\d+) -> (\d+),(\d+)$").unwrap(); | ||
52 | } | ||
53 | let mut max = 0; | ||
54 | let segs = s.lines().map(|l| { | ||
55 | let caps = RE.captures(l).expect("Malformed input"); | ||
56 | let x1 = caps.get(1).unwrap().as_str().parse().expect("Malformed input"); | ||
57 | let y1 = caps.get(2).unwrap().as_str().parse().expect("Malformed input"); | ||
58 | let x2 = caps.get(3).unwrap().as_str().parse().expect("Malformed input"); | ||
59 | let y2 = caps.get(4).unwrap().as_str().parse().expect("Malformed input"); | ||
60 | max = *[x1, x2, y1, y2, max].iter().max().unwrap(); | ||
61 | Segment(x1, y1, x2, y2) | ||
62 | }).collect(); | ||
63 | (max, segs) | ||
64 | } | ||
65 | |||
66 | fn range(from: u32, to: u32) -> Vec<u32> { | ||
67 | if from < to { | ||
68 | (from..=to).collect() | ||
69 | } else { | ||
70 | (to..=from).rev().collect() | ||
71 | } | ||
72 | } | ||
73 | |||
74 | #[cfg(test)] | ||
75 | mod tests { | ||
76 | use super::*; | ||
77 | |||
78 | const INPUT: &str = "0,9 -> 5,9 | ||
79 | 8,0 -> 0,8 | ||
80 | 9,4 -> 3,4 | ||
81 | 2,2 -> 2,1 | ||
82 | 7,0 -> 7,4 | ||
83 | 6,4 -> 2,0 | ||
84 | 0,9 -> 2,9 | ||
85 | 3,4 -> 1,4 | ||
86 | 0,0 -> 8,8 | ||
87 | 5,5 -> 8,2"; | ||
88 | |||
89 | #[test] | ||
90 | fn input_parsing() { | ||
91 | let (size, segments) = parse_input(INPUT); | ||
92 | assert_eq!(9,size); | ||
93 | assert_eq!(vec![ | ||
94 | Segment(0,9,5,9), | ||
95 | Segment(8,0,0,8), | ||
96 | Segment(9,4,3,4), | ||
97 | Segment(2,2,2,1), | ||
98 | Segment(7,0,7,4), | ||
99 | Segment(6,4,2,0), | ||
100 | Segment(0,9,2,9), | ||
101 | Segment(3,4,1,4), | ||
102 | Segment(0,0,8,8), | ||
103 | Segment(5,5,8,2), | ||
104 | ],segments); | ||
105 | } | ||
106 | |||
107 | #[test] | ||
108 | fn examples() { | ||
109 | let (size, segments) = parse_input(INPUT); | ||
110 | assert_eq!(vec![ | ||
111 | 0,0,0,0,0,0,0,1,0,0, | ||
112 | 0,0,1,0,0,0,0,1,0,0, | ||
113 | 0,0,1,0,0,0,0,1,0,0, | ||
114 | 0,0,0,0,0,0,0,1,0,0, | ||
115 | 0,1,1,2,1,1,1,2,1,1, | ||
116 | 0,0,0,0,0,0,0,0,0,0, | ||
117 | 0,0,0,0,0,0,0,0,0,0, | ||
118 | 0,0,0,0,0,0,0,0,0,0, | ||
119 | 0,0,0,0,0,0,0,0,0,0, | ||
120 | 2,2,2,1,1,1,0,0,0,0 | ||
121 | ], radar(&segments, size, false)); | ||
122 | assert_eq!(vec![ | ||
123 | 1,0,1,0,0,0,0,1,1,0, | ||
124 | 0,1,1,1,0,0,0,2,0,0, | ||
125 | 0,0,2,0,1,0,1,1,1,0, | ||
126 | 0,0,0,1,0,2,0,2,0,0, | ||
127 | 0,1,1,2,3,1,3,2,1,1, | ||
128 | 0,0,0,1,0,2,0,0,0,0, | ||
129 | 0,0,1,0,0,0,1,0,0,0, | ||
130 | 0,1,0,0,0,0,0,1,0,0, | ||
131 | 1,0,0,0,0,0,0,0,1,0, | ||
132 | 2,2,2,1,1,1,0,0,0,0 | ||
133 | ], radar(&segments, size, true)) | ||
134 | } | ||
135 | |||
136 | } | ||