Skip to content

Instantly share code, notes, and snippets.

@svantelidman
Last active December 6, 2019 20:54
Show Gist options
  • Save svantelidman/fb5049540271073aaf08fef6e616349a to your computer and use it in GitHub Desktop.
Save svantelidman/fb5049540271073aaf08fef6e616349a to your computer and use it in GitHub Desktop.
use std::io::{BufReader, BufRead};
use std::env;
use std::fs::File;
use std::collections::HashMap;
fn main() {
let args: Vec<String> = env::args().collect();
let orbit_file = &args[1];
let orbits = load_orbits(orbit_file);
let com = planet_code("COM");
println!("Total orbits: {}", count_orbits(com, &orbits));
let you = planet_code("YOU");
let san = planet_code("SAN");
println!("Minumum transitions: {}", find_min_transitions(com, you, san, &orbits));
}
fn find_min_transitions(com: i64,a: i64, b: i64, orbits: &HashMap<i64, i64>) -> i32 {
let a_path = build_path_to(com, a, orbits);
let b_path = build_path_to(com, b, orbits);
let mut base_ind = 0;
loop {
if a_path[base_ind] != b_path[base_ind] {
break;
}
base_ind += 1;
}
(a_path.len() + b_path.len() - 2 * base_ind - 2) as i32
}
fn build_path_to(com: i64, planet: i64, orbits: &HashMap<i64, i64>) -> Vec<i64> {
let mut path: Vec<i64> = vec![];
let mut p = planet;
loop {
path.push(p as i64);
if orbits[&p] == com {
break;
}
p = orbits[&p]
}
path.reverse();
path
}
fn count_orbits(com: i64, orbits: &HashMap<i64, i64> ) -> i32 {
orbits.keys().fold(0, |acc, ind| acc + count_steps(com, ind , orbits))
}
fn count_steps(com: i64, key: &i64, orbits: &HashMap<i64, i64>) -> i32 {
return if *key == com {
1
} else {
1 + count_steps(com, &orbits[key], orbits)
}
}
fn load_orbits(program_file: &String) -> HashMap<i64, i64> {
let mut orbits: HashMap<i64, i64> = HashMap::new();
let file = File::open(program_file).expect("Could not open program file!");
let reader = BufReader::new(file);
for line in reader.lines() {
let line = line.expect("Could not read from stdin");
let parts = line.split(")").collect::<Vec<&str>>();
let p1 = planet_code(parts[0]);
let p2 = planet_code(parts[1]);
orbits.insert(p2, p1);
}
orbits
}
fn planet_code(s: &str) -> i64 {
s.as_bytes().iter().fold(0, |acc, b| (acc << 8) + (*b as u64)) as i64
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment