Browse Source

WIP day 6: reading coords, creating grid

Tyler Hallada 5 years ago
parent
commit
7307f6a76e
3 changed files with 247 additions and 0 deletions
  1. 6 0
      inputs/6_test.txt
  2. 240 0
      src/day6.rs
  3. 1 0
      src/main.rs

+ 6 - 0
inputs/6_test.txt

@@ -0,0 +1,6 @@
1
+1, 1
2
+1, 6
3
+8, 3
4
+3, 4
5
+5, 5
6
+8, 9

+ 240 - 0
src/day6.rs

@@ -0,0 +1,240 @@
1
+extern crate regex;
2
+
3
+use std::error::Error;
4
+use std::fs::File;
5
+use std::io::{BufRead, BufReader};
6
+use std::{fmt, mem};
7
+use std::collections::HashMap;
8
+
9
+use regex::{Regex, Captures};
10
+
11
+const INPUT: &str = "inputs/6.txt";
12
+
13
+#[derive(Debug, PartialEq)]
14
+struct Coordinate {
15
+    x: u32,
16
+    y: u32,
17
+}
18
+
19
+#[derive(Debug, PartialEq)]
20
+enum GridPoint {
21
+    Unfilled {
22
+        x: u32,
23
+        y: u32,
24
+    },
25
+    Tied {
26
+        x: u32,
27
+        y: u32,
28
+        closest_dist: u32,
29
+    },
30
+    Filled {
31
+        x: u32,
32
+        y: u32,
33
+        closest_coord: Coordinate,
34
+        closest_dist: u32,
35
+    },
36
+}
37
+
38
+#[derive(Debug, Clone, PartialEq)]
39
+struct MalformedCoordinate {
40
+    details: String
41
+}
42
+
43
+impl MalformedCoordinate {
44
+    fn new(msg: &str) -> MalformedCoordinate {
45
+        MalformedCoordinate{ details: msg.to_string() }
46
+    }
47
+}
48
+
49
+impl fmt::Display for MalformedCoordinate {
50
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
51
+        write!(f, "{}", self.details)
52
+    }
53
+}
54
+
55
+impl Error for MalformedCoordinate {
56
+    fn description(&self) -> &str {
57
+        &self.details
58
+    }
59
+}
60
+
61
+fn read_coordinates(filename: &str) -> Result<Vec<Coordinate>, Box<Error>> {
62
+    let mut records: Vec<Coordinate> = Vec::new();
63
+    lazy_static! {
64
+        static ref COORDINATE_REGEX: Regex = Regex::new(
65
+            r"(?P<x>\d+), (?P<y>\d+)").unwrap();
66
+    }
67
+    let file = File::open(filename)?;
68
+    for line in BufReader::new(file).lines() {
69
+        match COORDINATE_REGEX.captures(&line?) {
70
+            Some(captures) => {
71
+                records.push(Coordinate {
72
+                    x: get_captured_field(&captures, "x")?.parse()?,
73
+                    y: get_captured_field(&captures, "y")?.parse()?,
74
+                });
75
+            },
76
+            None => return Err(Box::new(MalformedCoordinate {
77
+                details: "Malformed coordinate line, no fields could be found".to_string()
78
+            })),
79
+        };
80
+    }
81
+    Ok(records)
82
+}
83
+
84
+fn get_captured_field(captures: &Captures, field: &str) -> Result<String, Box<Error>> {
85
+    match captures.name(field) {
86
+        Some(capture) => Ok(String::from(capture.as_str())),
87
+        None => return Err(Box::new(MalformedCoordinate {
88
+            details: format!("Malformed coordinate line, field {} could not be found", field)
89
+        }))
90
+    }
91
+}
92
+
93
+fn get_boundary_coordinate(coords: Vec<Coordinate>) -> Coordinate {
94
+    let mut boundary_coord = Coordinate { x: 0, y: 0 };
95
+    for coord in coords {
96
+        if coord.x > boundary_coord.x {
97
+            boundary_coord.x = coord.x;
98
+        }
99
+        if coord.y > boundary_coord.y {
100
+            boundary_coord.y = coord.y;
101
+        }
102
+    }
103
+    boundary_coord
104
+}
105
+
106
+fn create_grid(boundary_coord: Coordinate) -> Vec<GridPoint> {
107
+    let mut grid = Vec::new();
108
+    for x in 0..boundary_coord.x + 1 {
109
+        for y in 0..boundary_coord.y + 1 {
110
+            grid.push(GridPoint::Unfilled { x, y });
111
+        }
112
+    }
113
+    grid
114
+}
115
+
116
+// fn fill_grid(
117
+    // grid: &mut Vec<GridPoint>,
118
+    // coords: Vec<Coordinate>,
119
+    // boundary_coord: Coordinate,
120
+// ) -> &mut Vec<GridPoint> {
121
+    // for coord in coords {
122
+        // fill_grid_with_coordinate(grid, coord, boundary_coord);
123
+    // }
124
+    // grid
125
+// }
126
+
127
+// fn fill_grid_with_coordinate(
128
+    // grid: &mut Vec<GridPoint>,
129
+    // point: GridPoint,
130
+    // coord: Coordinate,
131
+    // boundary_coord: Coordinate,
132
+// ) -> &mut Vec<GridPoint> {
133
+    // match point {
134
+        // GridPoint::Unfilled { x, y } => {
135
+            // mem::replace(
136
+                // &mut grid[x + ((boundary_coord.y + 1) * y)],
137
+                // GridPoint::Filled {
138
+                    // x: x,
139
+                    // y: y,
140
+                    // closest_coord: coord,
141
+                    // closest_dist: manhattan_dist(coord.x, coord.y, x, y),
142
+                // });
143
+        // }
144
+    // }
145
+// }
146
+
147
+fn manhattan_dist(x1: u32, y1: u32, x2: u32, y2: u32) -> u32 {
148
+    ((x2 as i32 - x1 as i32) + (y2 as i32 - y1 as i32)).abs() as u32
149
+}
150
+
151
+#[cfg(test)]
152
+mod tests {
153
+    use super::*;
154
+
155
+    const TEST_INPUT: &str = "inputs/6_test.txt";
156
+
157
+    #[test]
158
+    fn read_coordinates_file() {
159
+        assert_eq!(read_coordinates(TEST_INPUT).unwrap(), vec![
160
+            Coordinate {
161
+                x: 1,
162
+                y: 1,
163
+            },
164
+            Coordinate {
165
+                x: 1,
166
+                y: 6,
167
+            },
168
+            Coordinate {
169
+                x: 8,
170
+                y: 3,
171
+            },
172
+            Coordinate {
173
+                x: 3,
174
+                y: 4,
175
+            },
176
+            Coordinate {
177
+                x: 5,
178
+                y: 5,
179
+            },
180
+            Coordinate {
181
+                x: 8,
182
+                y: 9,
183
+            },
184
+        ]);
185
+    }
186
+
187
+    #[test]
188
+    fn gets_boundary_coordinate() {
189
+        assert_eq!(get_boundary_coordinate(vec![
190
+            Coordinate {
191
+                x: 1,
192
+                y: 1,
193
+            },
194
+            Coordinate {
195
+                x: 5,
196
+                y: 5,
197
+            },
198
+            Coordinate {
199
+                x: 2,
200
+                y: 7,
201
+            }
202
+        ]),
203
+            Coordinate {
204
+                x: 5,
205
+                y: 7,
206
+            }
207
+        )
208
+    }
209
+
210
+    #[test]
211
+    fn creates_grid() {
212
+        assert_eq!(
213
+            create_grid(Coordinate { x: 1, y: 1 }),
214
+            vec![
215
+                GridPoint::Unfilled {
216
+                    x: 0,
217
+                    y: 0,
218
+                },
219
+                GridPoint::Unfilled {
220
+                    x: 0,
221
+                    y: 1,
222
+                },
223
+                GridPoint::Unfilled {
224
+                    x: 1,
225
+                    y: 0,
226
+                },
227
+                GridPoint::Unfilled {
228
+                    x: 1,
229
+                    y: 1,
230
+                },
231
+            ])
232
+    }
233
+
234
+    #[test]
235
+    fn calculates_manhattan_dist() {
236
+        assert_eq!(manhattan_dist(0, 0, 2, 1), 3);
237
+        assert_eq!(manhattan_dist(0, 0, 0, 0), 0);
238
+        assert_eq!(manhattan_dist(2, 1, 0, 0), 3);
239
+    }
240
+}

+ 1 - 0
src/main.rs

@@ -6,6 +6,7 @@ mod day2;
6 6
 mod day3;
7 7
 mod day4;
8 8
 mod day5;
9
+mod day6;
9 10
 
10 11
 fn main() {
11 12
     println!("Day 1:");