aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorThomas Schmucker <ts@its1.de>2024-01-02 01:03:54 +0100
committerThomas Schmucker <ts@its1.de>2024-01-02 01:03:54 +0100
commit4168644780bd1924119feb61d596553fa17c7c94 (patch)
treea2360891b4852b5e1780c5ae392f05ea5899700a /src
parent43e8adeff6306073bf58631be796f409f293997f (diff)
downloadadvent-of-code-4168644780bd1924119feb61d596553fa17c7c94.tar.gz
advent-of-code-4168644780bd1924119feb61d596553fa17c7c94.tar.bz2
advent-of-code-4168644780bd1924119feb61d596553fa17c7c94.zip
Lösung für Tag 25
Diffstat (limited to 'src')
-rw-r--r--src/day25.cpp229
1 files changed, 229 insertions, 0 deletions
diff --git a/src/day25.cpp b/src/day25.cpp
new file mode 100644
index 0000000..b566725
--- /dev/null
+++ b/src/day25.cpp
@@ -0,0 +1,229 @@
1#include <algorithm>
2#include <cstdlib>
3#include <fstream>
4#include <iostream>
5#include <iterator>
6#include <list>
7#include <map>
8#include <queue>
9#include <set>
10#include <sstream>
11#include <string>
12#include <string_view>
13#include <vector>
14using namespace std;
15
16using graph_type = map<string, set<string>>;
17
18vector<string>
19split(const string& line, char sep)
20{
21 vector<string> parts;
22 stringstream input{ line };
23
24 for ( string part; getline(input, part, sep); ) {
25 parts.emplace_back(part);
26 }
27
28 return parts;
29}
30
31graph_type
32read_file(string_view filename)
33{
34 fstream input{ filename };
35 graph_type graph;
36
37 for ( string line; getline(input, line); ) {
38 const auto components = split(line.erase(line.find(':'), 1), ' ');
39
40 for ( size_t i = 1; i < components.size(); ++i ) {
41 graph[components[0]].insert(components[i]);
42 graph[components[i]].insert(components[0]);
43 }
44 }
45
46 return graph;
47}
48
49bool
50bfs(const graph_type& graph, const string& source, const string& dest, map<string, string>& parents) // NOLINT
51{
52 set<string> visited;
53
54 parents.clear();
55
56 queue<string> queue;
57 queue.emplace(source);
58
59 while ( !queue.empty() ) {
60 auto candidate = queue.front();
61 queue.pop();
62
63 if ( candidate == dest ) {
64 return true;
65 }
66
67 for ( const auto& neighbour: graph.at(candidate) ) {
68 if ( !visited.contains(neighbour) ) {
69 queue.emplace(neighbour);
70 parents[neighbour] = candidate;
71 visited.emplace(neighbour);
72 }
73 }
74 }
75
76 return false;
77}
78
79void
80dfs(const graph_type& graph, const string& source, set<string>& visited) // NOLINT
81{
82 visited.emplace(source);
83 for ( const auto& node: graph.at(source) ) {
84 if ( !visited.contains(node) ) {
85 dfs(graph, node, visited);
86 }
87 }
88}
89
90bool
91bfs1(graph_type graph, const string& source, const string& dest, function<void(const string&, const string&)> visit) // NOLINT
92{
93 set<string> visited;
94
95 queue<string> queue;
96 queue.emplace(source);
97
98 while ( !queue.empty() ) {
99 auto candidate = queue.front();
100 queue.pop();
101
102 if ( candidate == dest ) {
103 return true;
104 }
105
106 for ( const auto& neighbour: graph[candidate] ) {
107 if ( !visited.contains(neighbour) ) {
108 queue.emplace(neighbour);
109
110 visit(candidate, neighbour);
111 visited.emplace(neighbour);
112 }
113 }
114 }
115 return false;
116}
117
118void
119print_graph_stats(const graph_type& graph)
120{
121 size_t nodes = 0;
122 size_t edges = 0;
123 for ( const auto& link: graph ) {
124 nodes++;
125 edges += link.second.size();
126 }
127 cout << nodes << ", " << edges / 2 << endl;
128}
129
130void
131part1(graph_type graph)
132{
133 srand(unsigned(time(nullptr)));
134
135 vector<string> nodes(graph.size());
136 for ( const auto& foo: graph ) {
137 nodes.emplace_back(foo.first);
138 }
139
140 map<tuple<string, string>, int> counter;
141 for ( size_t idx = 0; idx != 2; ++idx ) {
142 for ( const auto& second: graph ) {
143 bfs1(graph, nodes[size_t(rand()) % nodes.size()], second.first, [&](const string& candidate, const string& neighbour) {
144 if ( candidate < neighbour ) {
145 counter[make_tuple(candidate, neighbour)]++;
146 }
147 else {
148 counter[make_tuple(neighbour, candidate)]++;
149 }
150 });
151 }
152 }
153
154 vector<tuple<tuple<string, string>, int>> all_links{ counter.begin(), counter.end() };
155
156 sort(all_links.begin(), all_links.end(), [](const auto& lhs, const auto& rhs) {
157 return get<1>(lhs) > get<1>(rhs);
158 });
159
160 for ( size_t i = 0; i != 3; ++i ) {
161 const auto [links, num] = all_links[i];
162 const auto [lhs, rhs] = links;
163
164 graph[lhs].erase(rhs);
165 graph[rhs].erase(lhs);
166 }
167
168 set<string> reachable;
169 const auto start_from_a = get<0>(get<0>(all_links[0]));
170 bfs1(graph, start_from_a, "--not there--", [&](const string& candidate, const string& neighbour) {
171 reachable.insert(candidate);
172 reachable.insert(neighbour);
173 });
174
175 set<string> reachable2;
176 const auto start_from_b = get<1>(get<0>(all_links[0]));
177 bfs1(graph, start_from_b, "--not there--", [&](const string& candidate, const string& neighbour) {
178 reachable2.insert(candidate);
179 reachable2.insert(neighbour);
180 });
181
182 cout << reachable.size() * reachable2.size() << endl;
183}
184
185void
186print_graph(const graph_type& graph)
187{
188 for ( const auto& node: graph ) {
189 cout << node.first << ": ";
190 copy(node.second.begin(), node.second.end(), ostream_iterator<string>(cout, ", "));
191 cout << endl;
192 }
193}
194
195graph_type
196get_rgraph(const graph_type& graph)
197{
198 graph_type rgraph;
199 for ( const auto& node: graph ) {
200 for ( const auto& link: node.second ) {
201 rgraph[link].insert(node.first);
202 }
203 }
204 return rgraph;
205}
206
207int
208main()
209{
210 auto graph = read_file("data/day25.txt");
211
212 // print_graph(graph);
213
214 part1(graph);
215
216 // print_graph(graph);
217 // cout << " ------------ " << endl;
218 // print_graph(get_rgraph(graph));
219 // cout << " ------------ " << endl;
220 // print_graph(get_rgraph(get_rgraph(graph)));
221
222 // map<string, string> parents;
223
224 // if ( bfs(graph, "jqt", "bvb", parents) ) {
225 // for ( const auto& [lhs, rhs]: parents ) {
226 // cout << lhs << ": " << rhs << endl;
227 // }
228 // }
229}