From c234561337bb5ec5ccdd353ab368befdbb3fab4e Mon Sep 17 00:00:00 2001 From: Tyler Hallada Date: Sun, 8 Dec 2019 19:01:49 -0500 Subject: [PATCH] Completed day 6 part 2 --- day6/input/test2.txt | 13 +++++++ day6/src/main.rs | 85 ++++++++++++++++++++++++++++++++++++++++---- 2 files changed, 91 insertions(+), 7 deletions(-) create mode 100644 day6/input/test2.txt diff --git a/day6/input/test2.txt b/day6/input/test2.txt new file mode 100644 index 0000000..a1007c6 --- /dev/null +++ b/day6/input/test2.txt @@ -0,0 +1,13 @@ +COM)B +B)C +C)D +D)E +E)F +B)G +G)H +D)I +E)J +J)K +K)L +K)YOU +I)SAN diff --git a/day6/src/main.rs b/day6/src/main.rs index 91da14f..9d0371d 100644 --- a/day6/src/main.rs +++ b/day6/src/main.rs @@ -1,4 +1,4 @@ -use std::collections::HashMap; +use std::collections::{HashMap, HashSet}; use std::error::Error; use std::fs::File; use std::io::{prelude::*, BufReader}; @@ -77,18 +77,54 @@ fn get_orbit_count_checksum(orbit_map: &OrbitMap) -> u32 { checksum } +fn get_orbital_transfers( + orbit_map: &OrbitMap, + source: NodeIndex, + destination: NodeIndex, + visited: &mut HashSet, +) -> Option { + visited.insert(source); + for neighbor in orbit_map.graph.neighbors_undirected(source) { + if neighbor == destination { + return Some(visited.len()); + } else if !visited.contains(&neighbor) { + if let Some(neighbor_transfers) = + get_orbital_transfers(orbit_map, neighbor, destination, &mut visited.clone()) + { + return Some(neighbor_transfers); + } + } + } + None +} + fn solve_part1() -> Result { let orbit_map = read_orbit_map(INPUT)?; Ok(get_orbit_count_checksum(&orbit_map)) } -fn solve_part2() -> Result { +fn solve_part2() -> Result { let orbit_map = read_orbit_map(INPUT)?; - let you = orbit_map.map.get("YOU").expect("YOU not found in orbit map"); - let san = orbit_map.map.get("SAN").expect("SAN not found in orbit map"); - // let mut bfs = Bfs::new(&orbit_map.graph, *you); - // that BFS doesn't tell me the edges from node for each iteration. guess I'll roll my own - Ok(0) + let you = orbit_map + .map + .get("YOU") + .expect("YOU not found in orbit map"); + let you_mass = orbit_map + .graph + .neighbors_directed(*you, Direction::Outgoing) + .next() + .expect("YOU is not orbiting a mass"); + let san = orbit_map + .map + .get("SAN") + .expect("SAN not found in orbit map"); + let san_mass = orbit_map + .graph + .neighbors_directed(*san, Direction::Outgoing) + .next() + .expect("SAN is not orbiting a mass"); + let transfers = get_orbital_transfers(&orbit_map, you_mass, san_mass, &mut HashSet::new()); + Ok(transfers.expect("No path found between YOU and SAN")) } fn main() -> Result<()> { @@ -103,6 +139,7 @@ mod tests { use super::*; const TEST_INPUT: &str = "input/test.txt"; + const TEST_INPUT2: &str = "input/test2.txt"; #[test] fn reads_orbit_map() { @@ -138,4 +175,38 @@ mod tests { let orbit_map = read_orbit_map(TEST_INPUT).unwrap(); assert_eq!(get_orbit_count_checksum(&orbit_map), 42) } + + #[test] + fn finds_orbital_transfers_between_objects() { + let orbit_map = read_orbit_map(TEST_INPUT2).unwrap(); + assert_eq!( + get_orbital_transfers( + &orbit_map, + *orbit_map.map.get("K").unwrap(), + *orbit_map.map.get("I").unwrap(), + &mut HashSet::new() + ).unwrap(), + 4 + ); + + assert_eq!( + get_orbital_transfers( + &orbit_map, + *orbit_map.map.get("K").unwrap(), + *orbit_map.map.get("J").unwrap(), + &mut HashSet::new() + ).unwrap(), + 1 + ); + + assert_eq!( + get_orbital_transfers( + &orbit_map, + *orbit_map.map.get("YOU").unwrap(), + *orbit_map.map.get("L").unwrap(), + &mut HashSet::new() + ).unwrap(), + 2 + ); + } }