aboutsummaryrefslogtreecommitdiff
path: root/2018/src/day10.cpp
diff options
context:
space:
mode:
authorThomas Schmucker <ts@its1.de>2025-11-16 13:23:34 +0100
committerThomas Schmucker <ts@its1.de>2025-11-16 13:23:34 +0100
commit8c96639ec1f6757570510fc27f1c5fabece35eaf (patch)
tree3a2b2146b6e8a353fa4c5edd105790320cce2b26 /2018/src/day10.cpp
parentbdd35a7bee7f23c912d0c453abc263805d8d8ccf (diff)
downloadadvent-of-code-8c96639ec1f6757570510fc27f1c5fabece35eaf.tar.gz
advent-of-code-8c96639ec1f6757570510fc27f1c5fabece35eaf.tar.bz2
advent-of-code-8c96639ec1f6757570510fc27f1c5fabece35eaf.zip
aoc 2018, days 1-11
Diffstat (limited to '2018/src/day10.cpp')
-rw-r--r--2018/src/day10.cpp137
1 files changed, 137 insertions, 0 deletions
diff --git a/2018/src/day10.cpp b/2018/src/day10.cpp
new file mode 100644
index 0000000..43de95c
--- /dev/null
+++ b/2018/src/day10.cpp
@@ -0,0 +1,137 @@
1#include <filesystem>
2#include <fstream>
3#include <iostream>
4#include <regex>
5#include <set>
6#include <tuple>
7#include <vector>
8
9using namespace std;
10
11namespace {
12
13struct Point {
14 long x;
15 long y;
16 long vx;
17 long vy;
18};
19
20vector<Point>
21read_file(const filesystem::path& filename)
22{
23 ifstream file{ filename };
24
25 static const regex pattern{ R"(position=<\s*(-?\d+)\s*,\s*(-?\d+)\s*>\s*velocity=<\s*(-?\d+)\s*,\s*(-?\d+)\s*>)" };
26
27 vector<Point> data;
28 for ( string line; getline(file, line); ) {
29 smatch match;
30 if ( regex_match(line, match, pattern) ) {
31 auto x = stol(match[1]);
32 auto y = stol(match[2]);
33 auto vx = stol(match[3]);
34 auto vy = stol(match[4]);
35
36 data.emplace_back(x, y, vx, vy);
37 }
38 }
39
40 return data;
41}
42
43void
44get_bounding_box(const vector<Point>& points, long& min_x, long& min_y, long& max_x, long& max_y)
45{
46 min_x = numeric_limits<long>::max();
47 min_y = numeric_limits<long>::max();
48 max_x = numeric_limits<long>::min();
49 max_y = numeric_limits<long>::min();
50
51 for ( const auto& point: points ) {
52 min_x = min(min_x, point.x);
53 min_y = min(min_y, point.y);
54 max_x = max(max_x, point.x);
55 max_y = max(max_y, point.y);
56 }
57}
58
59long
60bounding_area(const vector<Point>& points)
61{
62 long min_x = 0;
63 long min_y = 0;
64 long max_x = 0;
65 long max_y = 0;
66 get_bounding_box(points, min_x, min_y, max_x, max_y);
67 return 1L * (max_x - min_x + 1) * (max_y - min_y + 1);
68}
69
70void
71update(vector<Point>& points)
72{
73 for ( auto& point: points ) {
74 point.x += point.vx;
75 point.y += point.vy;
76 }
77}
78
79tuple<int, vector<Point>>
80get_best(vector<Point> points)
81{
82 auto best_area = numeric_limits<long>::max();
83
84 vector<Point> best;
85 int best_t = 0;
86
87 for ( int i = 0; i != 100'000; ++i ) {
88 update(points);
89
90 auto area = bounding_area(points);
91 if ( area < best_area ) {
92 best_area = area;
93 best = points;
94 best_t = i + 1;
95 }
96 }
97 return { best_t, best };
98}
99
100void
101print(const vector<Point>& points)
102{
103 set<tuple<long, long>> grid;
104 for ( const auto [x, y, vx, vy]: points ) {
105 grid.emplace(x, y);
106 }
107
108 long min_x = 0;
109 long min_y = 0;
110 long max_x = 0;
111 long max_y = 0;
112 get_bounding_box(points, min_x, min_y, max_x, max_y);
113
114 for ( long y = min_y; y <= max_y; ++y ) {
115 for ( long x = min_x; x <= max_x; ++x ) {
116 cout << (grid.contains({ x, y }) ? '#' : ' ');
117 }
118 cout << '\n';
119 }
120}
121
122void
123solve(const vector<Point>& points)
124{
125 auto [time, best_points] = get_best(points);
126 print(best_points);
127 cout << "Part 2: " << time << '\n';
128}
129
130} // namespace
131
132int
133main()
134{
135 auto data = read_file("data/day10.txt");
136 solve(data);
137}