mirror of
https://github.com/wezm/advent-of-code.git
synced 2024-12-18 18:29:55 +00:00
Day 6 part 2
This commit is contained in:
parent
69c072e211
commit
102a98fc82
1 changed files with 64 additions and 2 deletions
|
@ -14,6 +14,7 @@ fn main() -> io::Result<()> {
|
||||||
let orbits = parse_input(&input);
|
let orbits = parse_input(&input);
|
||||||
|
|
||||||
println!("Part 1: {}", number_of_orbits(&orbits));
|
println!("Part 1: {}", number_of_orbits(&orbits));
|
||||||
|
println!("Part 2: {}", orbital_transfers(&orbits, "YOU", "SAN"));
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -36,6 +37,32 @@ fn number_of_orbits(input: &[Orbit<'_>]) -> usize {
|
||||||
.sum()
|
.sum()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn orbital_transfers(input: &[Orbit<'_>], from: &str, to: &str) -> usize {
|
||||||
|
let nodes = build_tree(input);
|
||||||
|
|
||||||
|
// Find the to and from nodes
|
||||||
|
let from = nodes
|
||||||
|
.iter()
|
||||||
|
.find(|node| node.name == from)
|
||||||
|
.expect("unable to find from node");
|
||||||
|
let to = nodes
|
||||||
|
.iter()
|
||||||
|
.find(|node| node.name == to)
|
||||||
|
.expect("unable to find to node");
|
||||||
|
|
||||||
|
// Find the longest shared path they have on the way to COM and then the two remaining parts
|
||||||
|
// give the path between them.
|
||||||
|
let from_nodes_to_com = nodes_to_com(&nodes, from, Vec::new());
|
||||||
|
let to_nodes_to_com = nodes_to_com(&nodes, to, Vec::new());
|
||||||
|
let mut i = 0;
|
||||||
|
while from_nodes_to_com[i].name == to_nodes_to_com[i].name {
|
||||||
|
i += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// - 2 since we don't count the path from 'from' to the object it's orbiting. Same for 'to'.
|
||||||
|
from_nodes_to_com[i..].len() + to_nodes_to_com[i..].len() - 2
|
||||||
|
}
|
||||||
|
|
||||||
fn build_tree<'a>(input: &'a [Orbit<'a>]) -> Vec<Node<'a>> {
|
fn build_tree<'a>(input: &'a [Orbit<'a>]) -> Vec<Node<'a>> {
|
||||||
// Build the tree from the input
|
// Build the tree from the input
|
||||||
let mut nodes: Vec<Node<'_>> = Vec::with_capacity(input.len());
|
let mut nodes: Vec<Node<'_>> = Vec::with_capacity(input.len());
|
||||||
|
@ -85,11 +112,25 @@ fn count_orbits(nodes: &[Node], node_index: usize, count: usize) -> usize {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn nodes_to_com<'a>(
|
||||||
|
nodes: &'a [Node],
|
||||||
|
current_node: &'a Node,
|
||||||
|
mut path: Vec<&'a Node<'a>>,
|
||||||
|
) -> Vec<&'a Node<'a>> {
|
||||||
|
path.push(current_node);
|
||||||
|
if let Some(parent_index) = current_node.parent {
|
||||||
|
nodes_to_com(nodes, &nodes[parent_index], path)
|
||||||
|
} else {
|
||||||
|
path.reverse();
|
||||||
|
path
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
const TEST_INPUT: &str = "B)C
|
const TEST_INPUT1: &str = "B)C
|
||||||
COM)B
|
COM)B
|
||||||
C)D
|
C)D
|
||||||
D)E
|
D)E
|
||||||
|
@ -100,11 +141,32 @@ D)I
|
||||||
E)J
|
E)J
|
||||||
J)K
|
J)K
|
||||||
K)L
|
K)L
|
||||||
|
";
|
||||||
|
|
||||||
|
const TEST_INPUT2: &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
|
||||||
";
|
";
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_number_of_orbits() {
|
fn test_number_of_orbits() {
|
||||||
let orbits = parse_input(TEST_INPUT);
|
let orbits = parse_input(TEST_INPUT1);
|
||||||
assert_eq!(number_of_orbits(&orbits), 42);
|
assert_eq!(number_of_orbits(&orbits), 42);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_orbital_transfers() {
|
||||||
|
let orbits = parse_input(TEST_INPUT2);
|
||||||
|
assert_eq!(orbital_transfers(&orbits, "YOU", "SAN"), 4);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue