Browse Source

Completed day 6 part 2

Tyler Hallada 4 years ago
parent
commit
c234561337
2 changed files with 91 additions and 7 deletions
  1. 13 0
      day6/input/test2.txt
  2. 78 7
      day6/src/main.rs

+ 13 - 0
day6/input/test2.txt

@@ -0,0 +1,13 @@
1
+COM)B
2
+B)C
3
+C)D
4
+D)E
5
+E)F
6
+B)G
7
+G)H
8
+D)I
9
+E)J
10
+J)K
11
+K)L
12
+K)YOU
13
+I)SAN

+ 78 - 7
day6/src/main.rs

@@ -1,4 +1,4 @@
1
-use std::collections::HashMap;
1
+use std::collections::{HashMap, HashSet};
2 2
 use std::error::Error;
3 3
 use std::fs::File;
4 4
 use std::io::{prelude::*, BufReader};
@@ -77,18 +77,54 @@ fn get_orbit_count_checksum(orbit_map: &OrbitMap) -> u32 {
77 77
     checksum
78 78
 }
79 79
 
80
+fn get_orbital_transfers(
81
+    orbit_map: &OrbitMap,
82
+    source: NodeIndex,
83
+    destination: NodeIndex,
84
+    visited: &mut HashSet<NodeIndex>,
85
+) -> Option<usize> {
86
+    visited.insert(source);
87
+    for neighbor in orbit_map.graph.neighbors_undirected(source) {
88
+        if neighbor == destination {
89
+            return Some(visited.len());
90
+        } else if !visited.contains(&neighbor) {
91
+            if let Some(neighbor_transfers) =
92
+                get_orbital_transfers(orbit_map, neighbor, destination, &mut visited.clone())
93
+            {
94
+                return Some(neighbor_transfers);
95
+            }
96
+        }
97
+    }
98
+    None
99
+}
100
+
80 101
 fn solve_part1() -> Result<u32> {
81 102
     let orbit_map = read_orbit_map(INPUT)?;
82 103
     Ok(get_orbit_count_checksum(&orbit_map))
83 104
 }
84 105
 
85
-fn solve_part2() -> Result<i32> {
106
+fn solve_part2() -> Result<usize> {
86 107
     let orbit_map = read_orbit_map(INPUT)?;
87
-    let you = orbit_map.map.get("YOU").expect("YOU not found in orbit map");
88
-    let san = orbit_map.map.get("SAN").expect("SAN not found in orbit map");
89
-    // let mut bfs = Bfs::new(&orbit_map.graph, *you);
90
-    // that BFS doesn't tell me the edges from node for each iteration. guess I'll roll my own
91
-    Ok(0)
108
+    let you = orbit_map
109
+        .map
110
+        .get("YOU")
111
+        .expect("YOU not found in orbit map");
112
+    let you_mass = orbit_map
113
+        .graph
114
+        .neighbors_directed(*you, Direction::Outgoing)
115
+        .next()
116
+        .expect("YOU is not orbiting a mass");
117
+    let san = orbit_map
118
+        .map
119
+        .get("SAN")
120
+        .expect("SAN not found in orbit map");
121
+    let san_mass = orbit_map
122
+        .graph
123
+        .neighbors_directed(*san, Direction::Outgoing)
124
+        .next()
125
+        .expect("SAN is not orbiting a mass");
126
+    let transfers = get_orbital_transfers(&orbit_map, you_mass, san_mass, &mut HashSet::new());
127
+    Ok(transfers.expect("No path found between YOU and SAN"))
92 128
 }
93 129
 
94 130
 fn main() -> Result<()> {
@@ -103,6 +139,7 @@ mod tests {
103 139
     use super::*;
104 140
 
105 141
     const TEST_INPUT: &str = "input/test.txt";
142
+    const TEST_INPUT2: &str = "input/test2.txt";
106 143
 
107 144
     #[test]
108 145
     fn reads_orbit_map() {
@@ -138,4 +175,38 @@ mod tests {
138 175
         let orbit_map = read_orbit_map(TEST_INPUT).unwrap();
139 176
         assert_eq!(get_orbit_count_checksum(&orbit_map), 42)
140 177
     }
178
+
179
+    #[test]
180
+    fn finds_orbital_transfers_between_objects() {
181
+        let orbit_map = read_orbit_map(TEST_INPUT2).unwrap();
182
+        assert_eq!(
183
+            get_orbital_transfers(
184
+                &orbit_map,
185
+                *orbit_map.map.get("K").unwrap(),
186
+                *orbit_map.map.get("I").unwrap(),
187
+                &mut HashSet::new()
188
+            ).unwrap(),
189
+            4
190
+        );
191
+
192
+        assert_eq!(
193
+            get_orbital_transfers(
194
+                &orbit_map,
195
+                *orbit_map.map.get("K").unwrap(),
196
+                *orbit_map.map.get("J").unwrap(),
197
+                &mut HashSet::new()
198
+            ).unwrap(),
199
+            1
200
+        );
201
+
202
+        assert_eq!(
203
+            get_orbital_transfers(
204
+                &orbit_map,
205
+                *orbit_map.map.get("YOU").unwrap(),
206
+                *orbit_map.map.get("L").unwrap(),
207
+                &mut HashSet::new()
208
+            ).unwrap(),
209
+            2
210
+        );
211
+    }
141 212
 }