Ryan is an engineer in the Sacramento Area with a focus in Python, Ruby, and Rust. Bash/Python Exercism mentor. Coding, physics, calculus, music, woodworking. Looking for work!
After a weekend of flu, I'm back in action--albeit about four days behind the pace now. I'll catch up. Here's today's solution in Rust. No BFS for me. Just a hashtable of children, and a (likely inefficient, but good enough) reverse lookup to do some ancestor math.
/// Day 6: Universal Orbit Map/// /// Find out how many orbits there are in a galaxy mapusestd::fs::File;usestd::io::prelude::*;usestd::io::BufReader;usestd::collections::HashMap;/// An orbit map is a mapping of nodes to the names of their children.typeOMap=HashMap<String,Vec<String>>;/// Expects a list of mappings of the form AAA)BBB, one per line./// AAA here is the parent of BBB (and potentially many others)./// Nodes only have one parent.fnparse_input()->OMap{letbuf=BufReader::new(File::open("data/day6.txt").unwrap());letmutresult:OMap=HashMap::new();forlineinbuf.lines(){lettext=line.unwrap();letmutentities=text.split(")");letparent=entities.next().unwrap();letchild=entities.next().unwrap();letchildren=result.entry(parent.to_string()).or_default();children.push(child.to_string());result.entry(child.to_string()).or_default();}result}/// Count the sum of the number of steps it is from each node in a tree/// to the root./// /// The result is the sum of a node's distance from COM and all of its/// children's orbit counts.fncount_orbits(depth:usize,parent:&str,orbit_map:&OMap)->usize{letchildren=&orbit_map[parent];ifchildren.len()==0{depth}else{letchildren_total:usize=children.iter().map(|c|count_orbits(depth+1,c,orbit_map)).sum();depth+children_total}}/// Builds a list of the ancestors of an entity starting with its/// parent and ending with COM. Or, the String version of COM./// Or... the &String version of COM. Shut up, rust is stupid.fnancestors<'a>(orbit_map:&'aOMap,a:&String,mutso_far:Vec<&'aString>)->Vec<&'aString>{for(parent,children)inorbit_map.iter(){ifchildren.contains(a)&&parent=="COM"{so_far.push(parent);returnso_far;}elseifchildren.contains(a){so_far.push(parent);returnancestors(orbit_map,parent,so_far);}}panic!("Couldn't find parent!");}/// Find out how many steps minimum are between the parents of a and b./// /// Assumes that the orbit is acyclic with only one root,/// and thus, there is only one way to get from one to the other, /// up through the tree to a common ancestor and back downfnsteps_between(orbit_map:&OMap,a:&String,b:&String)->usize{leta_ancestors=ancestors(orbit_map,a,Vec::new());letb_ancestors=ancestors(orbit_map,b,Vec::new());letsame=a_ancestors.iter().rev().zip(b_ancestors.iter().rev()).filter(|(x,y)|x==y).count();(a_ancestors.len()-same)+(b_ancestors.len()-same)}pubfnrun(){letorbit_map=parse_input();letparent="COM".to_string();println!("Total orbits: {}",count_orbits(0,&parent,&orbit_map));letme="YOU".to_string();letsanta="SAN".to_string();println!("Distance between me and Santa: {}",steps_between(&orbit_map,&me,&santa))}
For further actions, you may consider blocking this person and/or reporting abuse
We're a place where coders share, stay up-to-date and grow their careers.
After a weekend of flu, I'm back in action--albeit about four days behind the pace now. I'll catch up. Here's today's solution in Rust. No BFS for me. Just a hashtable of children, and a (likely inefficient, but good enough) reverse lookup to do some ancestor math.