-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathday6_orbit-map.cpp
103 lines (88 loc) · 3.04 KB
/
day6_orbit-map.cpp
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
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
#include <iostream>
#include <cassert>
#include <string>
#include "utils.cpp"
unordered_map<string, string> parseToOrbitMap(const vector<string> &orbitsInfo)
{
unordered_map<string, string> reverseOrbitGraph;
for (auto orbit : orbitsInfo)
{
const auto [center, satellite] = cut(orbit, ")");
reverseOrbitGraph[satellite] = center;
}
return reverseOrbitGraph;
}
struct OrbitsPathObject
{
string object;
size_t transfertFromSatellite;
};
struct OrbitsPathObjectHash
{
size_t operator() (const OrbitsPathObject &o) const noexcept {
return hash<string>()(o.object);
}
};
bool operator== (const OrbitsPathObject &p1, const OrbitsPathObject &p2) {
return p1.object == p2.object;
}
vector<OrbitsPathObject> orbitsPath(
const unordered_map<string, string> &orbitGraph,
string object,
vector<OrbitsPathObject> path = {}
)
{
const auto orbiting = orbitGraph.find(object);
if (orbiting == orbitGraph.end())
{
return path;
}
path.push_back({orbiting->second, path.size()});
return orbitsPath(orbitGraph, orbiting->second, path);
}
int orbitsSum(const unordered_map<string, string> &orbitGraph)
{
int orbitSum = 0;
for (auto it = orbitGraph.begin(); it != orbitGraph.end(); ++it)
{
orbitSum += orbitsPath(orbitGraph, it->first).size();
}
return orbitSum;
}
int minimalOrbitTransfer(
const unordered_map<string, string> &orbitGraph,
string start,
string destination
)
{
const auto startObjOrbitsPath = orbitsPath(orbitGraph, start);
const auto destObjOrbitsPath = orbitsPath(orbitGraph, destination);
unordered_set<OrbitsPathObject, OrbitsPathObjectHash> alreadySeen (startObjOrbitsPath.begin(), startObjOrbitsPath.end());
for(auto opo : destObjOrbitsPath) {
const auto objectSeen = alreadySeen.find(opo);
if (objectSeen != alreadySeen.end()) {
return opo.transfertFromSatellite + (*objectSeen).transfertFromSatellite;
}
}
return 0;
}
vector<string> testInput1{"COM)B", "B)C", "C)D", "D)E", "E)F", "B)G", "G)H", "D)I", "E)J", "J)K", "K)L"};
vector<string> testInput2{"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"};
int main(int argc, char const *argv[])
{
// Part 1
assert(orbitsPath(parseToOrbitMap(testInput1), "D").size() == 3);
assert(orbitsPath(parseToOrbitMap(testInput1), "L").size() == 7);
assert(orbitsPath(parseToOrbitMap(testInput1), "COM").size() == 0);
assert(orbitsSum(parseToOrbitMap(testInput1)) == 42);
const auto inputOrbitMap = parseToOrbitMap(getPuzzleInput("./inputs/aoc_day6_1.txt"));
const auto p1 = orbitsSum(inputOrbitMap);
cout << "Part 1, total number of direct and indirect orbits: " << p1 << "\n";
// Part 2
assert(minimalOrbitTransfer(parseToOrbitMap(testInput2), "YOU", "SAN") == 4);
assert(minimalOrbitTransfer(parseToOrbitMap(testInput2), "F", "SAN") == 2);
assert(minimalOrbitTransfer(parseToOrbitMap(testInput2), "H", "SAN") == 4);
const auto p2 = minimalOrbitTransfer(inputOrbitMap, "YOU", "SAN");
cout << "Part 2, minimum number of orbital transfers required: " << p2 << "\n";
return 0;
}