summaryrefslogtreecommitdiff
path: root/day5/src/main.rs
diff options
context:
space:
mode:
Diffstat (limited to 'day5/src/main.rs')
-rw-r--r--day5/src/main.rs136
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 @@
1use std::fs;
2use std::path::Path;
3use regex::Regex;
4use lazy_static::lazy_static;
5
6#[derive(Debug,PartialEq)]
7struct Segment(u32,u32,u32,u32);
8
9impl 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 */
19fn 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
29fn 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
49fn 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
66fn 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)]
75mod tests {
76 use super::*;
77
78 const INPUT: &str = "0,9 -> 5,9
798,0 -> 0,8
809,4 -> 3,4
812,2 -> 2,1
827,0 -> 7,4
836,4 -> 2,0
840,9 -> 2,9
853,4 -> 1,4
860,0 -> 8,8
875,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}