Browse Source

Day 3 part 2

Tyler Hallada 5 years ago
parent
commit
a3abcbf107
2 changed files with 46 additions and 12 deletions
  1. 45 12
      src/day3.rs
  2. 1 0
      src/main.rs

+ 45 - 12
src/day3.rs

@@ -4,13 +4,14 @@ use std::error::Error;
4 4
 use std::fs::File;
5 5
 use std::io::{BufRead, BufReader};
6 6
 use std::fmt;
7
-use std::collections::HashMap;
7
+use std::collections::{HashMap, HashSet};
8
+use std::iter::FromIterator;
8 9
 
9 10
 use regex::{Regex, Captures};
10 11
 
11 12
 const INPUT: &str = "inputs/3.txt";
12 13
 
13
-#[derive(Debug, PartialEq)]
14
+#[derive(Debug, PartialEq, Clone)]
14 15
 struct Claim {
15 16
     id: u32,
16 17
     left: u32,
@@ -19,7 +20,7 @@ struct Claim {
19 20
     height: u32,
20 21
 }
21 22
 
22
-#[derive(Debug, PartialEq, Eq, Hash)]
23
+#[derive(Debug, PartialEq, Eq, Hash, Clone)]
23 24
 struct Point {
24 25
     x: u32,
25 26
     y: u32,
@@ -52,14 +53,12 @@ pub fn solve_part1() -> Result<u32, Box<Error>> {
52 53
     Ok(count_overlapping_claimed_points(read_claims(INPUT)?))
53 54
 }
54 55
 
56
+pub fn solve_part2() -> Result<Option<u32>, Box<Error>> {
57
+    Ok(find_non_overlapping_claim(read_claims(INPUT)?))
58
+}
59
+
55 60
 fn count_overlapping_claimed_points(claims: Vec<Claim>) -> u32 {
56
-    let mut claimed_points: HashMap<Point, u32> = HashMap::new();
57
-    for claim in claims {
58
-        for point in list_points_in_claim(claim) {
59
-            let current_point = claimed_points.get(&point).unwrap_or(&0);
60
-            claimed_points.insert(point, current_point + 1);
61
-        }
62
-    }
61
+    let claimed_points = get_claimed_points(&claims);
63 62
     return claimed_points.values().fold(0, |acc, claims| {
64 63
         if claims > &1 {
65 64
             return acc + 1
@@ -68,7 +67,31 @@ fn count_overlapping_claimed_points(claims: Vec<Claim>) -> u32 {
68 67
     })
69 68
 }
70 69
 
71
-fn list_points_in_claim(claim: Claim) -> Vec<Point> {
70
+fn find_non_overlapping_claim(claims: Vec<Claim>) -> Option<u32> {
71
+    let claimed_points = get_claimed_points(&claims);
72
+    for claim in claims {
73
+        let points = list_points_in_claim(&claim);
74
+        let non_overlapping = points.iter().all(
75
+            |point| claimed_points.get(&point).unwrap_or(&0) < &2);
76
+        if non_overlapping {
77
+            return Some(claim.id);
78
+        }
79
+    }
80
+    None
81
+}
82
+
83
+fn get_claimed_points(claims: &Vec<Claim>) -> HashMap<Point, u32> {
84
+    let mut claimed_points: HashMap<Point, u32> = HashMap::new();
85
+    for claim in claims {
86
+        for point in list_points_in_claim(&claim) {
87
+            let current_point = claimed_points.get(&point).unwrap_or(&0);
88
+            claimed_points.insert(point, current_point + 1);
89
+        }
90
+    }
91
+    claimed_points
92
+}
93
+
94
+fn list_points_in_claim(claim: &Claim) -> Vec<Point> {
72 95
     let mut points = Vec::new();
73 96
     for x in 0..claim.width {
74 97
         for y in 0..claim.height {
@@ -142,7 +165,7 @@ mod tests {
142 165
 
143 166
     #[test]
144 167
     fn lists_points_in_claim() {
145
-        assert_eq!(list_points_in_claim(Claim { id: 1, left: 0, top: 0, width: 2, height: 2 }),
168
+        assert_eq!(list_points_in_claim(&Claim { id: 1, left: 0, top: 0, width: 2, height: 2 }),
146 169
             vec![
147 170
                 Point { x: 0, y: 0 },
148 171
                 Point { x: 0, y: 1 },
@@ -161,4 +184,14 @@ mod tests {
161 184
         ];
162 185
         assert_eq!(count_overlapping_claimed_points(test_claims), 4);
163 186
     }
187
+
188
+    #[test]
189
+    fn finds_non_overlapping_claim() {
190
+        let test_claims = vec![
191
+            Claim { id: 1, left: 1, top: 3, width: 4, height: 4 },
192
+            Claim { id: 2, left: 3, top: 1, width: 4, height: 4 },
193
+            Claim { id: 3, left: 5, top: 5, width: 2, height: 2 },
194
+        ];
195
+        assert_eq!(find_non_overlapping_claim(test_claims).unwrap(), 3);
196
+    }
164 197
 }

+ 1 - 0
src/main.rs

@@ -11,4 +11,5 @@ fn main() {
11 11
     println!("{}", day2::solve_part2().unwrap().unwrap());
12 12
     println!("Day 3:");
13 13
     println!("{}", day3::solve_part1().unwrap());
14
+    println!("{}", day3::solve_part2().unwrap().unwrap());
14 15
 }