-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy path06.ts
65 lines (60 loc) · 2.11 KB
/
06.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
// Parse the orbit pairs into tuples
// A)B\nB)C\nC)D => [[A, B], [B, C], [C, D]]
const parseOrbitPairs = (input: string): [string, string][] =>
input.split("\n").map((ln) => ln.split(")") as [string, string]);
type OrbitGraph = Map<string, string[]>;
// Create a bidirectional map of the orbits
// { "COM": ["B"], "B": ["COM", "C", "G"], ... }
const createOrbitGraph = (pairs: [string, string][]) => {
const graph: OrbitGraph = new Map();
for (const [a, b] of pairs) {
if (!graph.has(a)) graph.set(a, []);
if (!graph.has(b)) graph.set(b, []);
graph.get(a)?.push(b);
graph.get(b)?.push(a);
}
return graph;
};
// Find the total number of direct and indirect orbits in the graph
const getTotalOrbits = (graph: OrbitGraph, root = "COM"): number => {
const visited: Set<string> = new Set();
const depthFirstSearch = (node: string, depth = 0): number => {
if (visited.has(node)) return 0;
visited.add(node);
let count = depth;
for (const neighbor of graph.get(node) ?? []) {
count += depthFirstSearch(neighbor, depth + 1);
}
return count;
};
return depthFirstSearch(root);
};
// Find how many orbits need to be jumped to reach another node in the graph
const getTransfers = (graph: OrbitGraph, from = "YOU", to = "SAN"): number => {
const [start] = graph.get(from)!;
const [end] = graph.get(to)!;
const queue: [string, number][] = [[start, 0]];
const visited: Set<string> = new Set([start]);
while (queue.length) {
const [curr, transfers] = queue.shift()!;
if (curr === end) return transfers;
const neighbors = graph.get(curr) ?? [];
for (const neighbor of neighbors) {
if (!visited.has(neighbor)) {
visited.add(neighbor);
queue.push([neighbor, transfers + 1]);
}
}
}
throw new Error(`No path found from ${from} to ${to}`);
};
export function part1(input: string) {
const pairs = parseOrbitPairs(input);
const graph = createOrbitGraph(pairs);
return getTotalOrbits(graph);
}
export function part2(input: string) {
const pairs = parseOrbitPairs(input);
const graph = createOrbitGraph(pairs);
return getTransfers(graph);
}