Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- pub mod day06 {
- use lazy_static::lazy_static;
- use std::collections::HashMap;
- use std::fmt::Write;
- use indextree::Arena;
- use itertools::Itertools;
- fn count_orbits(arena: &Arena<&str>, node: indextree::NodeId, depth: i32) -> i32 {
- depth + node.children(&arena).map(|child| count_orbits(arena, child, depth + 1)).sum::<i32>()
- }
- pub fn run(file_string: String) {
- // Parse input into tuple pairs (not totally necessary)
- let pairs : Vec<(&str, &str)> = file_string.lines()
- .map(|line| line.split(")").next_tuple().unwrap())
- .collect();
- // Build graph
- let mut arena = &mut Arena::new();
- let mut id_map : HashMap<&str, indextree::NodeId> = HashMap::new();
- for (center, orbit) in &pairs {
- let center_id = *id_map.entry(center).or_insert_with(|| arena.new_node(*center));
- let orbit_id = *id_map.entry(orbit).or_insert_with(|| arena.new_node(*orbit));
- center_id.append(orbit_id, &mut arena);
- }
- // Part 1 - Compute total orbits from graph
- let total_orbits = count_orbits(arena, *id_map.get("COM").unwrap(), 0);
- writeln!(&mut result, "Day 6, Problem 1 - [{}]", total_orbits).unwrap(); // 270768
- // Part 2 - Find path between two arbitrary nodes
- let you_to_com : Vec<indextree::NodeId> = id_map.get("YOU").unwrap().ancestors(&arena).collect();
- let santa_to_com : Vec<indextree::NodeId> = id_map.get("SAN").unwrap().ancestors(&arena).collect();
- // Index of last shared object
- let transfer_point = you_to_com.iter().rev()
- .zip(santa_to_com.iter().rev())
- .take_while(|pair| pair.0 == pair.1)
- .count() - 1;
- // Compute transfers
- let transfers = (you_to_com.len() - transfer_point - 2) + (santa_to_com.len() - transfer_point - 2);
- writeln!(&mut result, "Day 6, Problem 2 - [{}]", transfers).unwrap(); // 451
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement