diff --git a/2017/day/12/problem.txt b/2017/day/12/problem.txt index 3f22692..cabaf1b 100644 --- a/2017/day/12/problem.txt +++ b/2017/day/12/problem.txt @@ -32,3 +32,13 @@ In this example, the following programs are in the group that contains program I Therefore, a total of 6 programs are in this group; all but program 1, which has a pipe that connects it to itself. How many programs are in the group that contains program ID 0? + +--- Part Two --- + +There are more programs than just the ones in the group containing program ID 0. The rest of them have no way of reaching that group, and still might have no way of reaching each other. + +A group is a collection of programs that can all communicate via pipes either directly or indirectly. The programs you identified just a moment ago are all part of the same group. Now, they would like you to determine the total number of groups. + +In the example above, there were 2 groups: one consisting of programs 0,2,3,4,5,6, and the other consisting solely of program 1. + +How many groups are there in total? diff --git a/2017/day/12/src/main.rs b/2017/day/12/src/main.rs index 09122ba..5e7157a 100644 --- a/2017/day/12/src/main.rs +++ b/2017/day/12/src/main.rs @@ -20,15 +20,38 @@ fn main() { programs.push(linked); } - println!("{}", reachable(&programs)); + println!("{}", reachable(0, &programs).len()); + println!("{}", groups(&programs)); } -fn reachable(list: &Vec>) -> usize { +// This isn't real pretty but it works +fn groups(list: &Vec>) -> usize { + let mut groups = 0; + let mut to_visit = HashSet::with_capacity(list.len()); + + for idx in 0..list.len() { + to_visit.insert(idx); + } + + while !to_visit.is_empty() { + let group = reachable(*to_visit.iter().next().unwrap(), list); + let mut new_to_visit = HashSet::new(); + for idx in to_visit.difference(&group) { + new_to_visit.insert(*idx); + } + to_visit = new_to_visit; + groups += 1 + } + + groups +} + +fn reachable(from: usize, list: &Vec>) -> HashSet { let mut visited = HashSet::new(); - visit(0, &mut visited, list); + visit(from, &mut visited, list); - visited.len() + visited } fn visit(pid: usize, visited: &mut HashSet, list: &Vec>) {