--- /dev/null
+use std::collections::HashMap;
+use std::cmp;
+
+// All planets indexing their parent (planet -> parent).
+type Orbits = HashMap<String, String>;
+
+pub fn build_orbits(orbits_str: &[&str]) -> Orbits {
+ let mut orbits = Orbits::new();
+ for orbit in orbits_str {
+ let planets: Vec<&str> = orbit.trim().split(')').collect();
+ orbits.insert(String::from(planets[1]), String::from(planets[0]));
+ }
+ orbits
+}
+
+fn parents<'a>(orbits: &'a Orbits, planet: &str) -> Vec<&'a str> {
+ let mut parents = Vec::<&str>::new();
+ let mut current_planet = planet;
+
+ loop {
+ match orbits.get(current_planet) {
+ Some (parent) => { parents.insert(0, parent); current_planet = parent; },
+ None => break
+ }
+ }
+
+ parents
+}
+
+pub fn total_direct_and_indirect_orbits(orbits: &Orbits) -> usize {
+ orbits.keys().fold(0, |sum, planet| { sum + parents(orbits, &planet).len() })
+}
+
+pub fn nb_orbital_transfers(orbits: &Orbits, loc1: &str, loc2: &str) -> usize {
+ let parents_loc1 = parents(orbits, loc1);
+ let parents_loc2 = parents(orbits, loc2);
+ for i in 0..cmp::min(parents_loc1.len(), parents_loc2.len()) {
+ if parents_loc1[i] != parents_loc2[i] {
+ return parents_loc1.len() + parents_loc2.len() - 2 * i
+ }
+ }
+ 0
+}
+
+#[cfg(test)]
+mod test {
+ use super::*;
+
+ #[test]
+ fn part1() {
+ let lines: Vec<&str> =
+ "COM)B
+ B)C
+ C)D
+ D)E
+ E)F
+ B)G
+ G)H
+ D)I
+ E)J
+ J)K
+ K)L".lines().collect();
+
+ let n = total_direct_and_indirect_orbits(&build_orbits(&lines));
+ assert_eq!(n, 42);
+ }
+
+ #[test]
+ fn part2() {
+ let lines: Vec<&str> =
+ "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".lines().collect();
+
+ let n = nb_orbital_transfers(&build_orbits(&lines), "SAN", "YOU");
+ assert_eq!(n, 4);
+ }
+}
\ No newline at end of file
mod day01;
mod day02;
mod day03;
+mod day06;
mod common;
fn day01() -> String {
)
}
+fn day06() -> String {
+ let file_content = fs::read_to_string("data/day06.input").unwrap();
+ let lines: Vec<&str> = file_content.lines().collect();
+ let orbits = day06::build_orbits(&lines);
+ format!("part1: {}, part2: {}", day06::total_direct_and_indirect_orbits(&orbits), day06::nb_orbital_transfers(&orbits, "SAN", "YOU"))
+}
+
fn format_micros(t: u128) -> String {
if t < 10_000 {
format!("{} μs", t)
let days: Vec<fn() -> String> = vec!(
day01,
day02,
- day03
+ day03,
+ day06
);
let args: Vec<String> = env::args().skip(1).collect();