aboutsummaryrefslogtreecommitdiff
path: root/2024
diff options
context:
space:
mode:
authorThomas Schmucker <ts@its1.de>2024-12-14 11:27:04 +0100
committerThomas Schmucker <ts@its1.de>2024-12-14 11:27:04 +0100
commitfc3cc642c620221cafed36c8c07da34bfb566843 (patch)
tree795b6cee0de7218b039544096724f7193dc6c4db /2024
parentf52b43d879218febd8d2cb69d74d94af8ec1fe31 (diff)
downloadadvent-of-code-fc3cc642c620221cafed36c8c07da34bfb566843.tar.gz
advent-of-code-fc3cc642c620221cafed36c8c07da34bfb566843.tar.bz2
advent-of-code-fc3cc642c620221cafed36c8c07da34bfb566843.zip
aoc 2024, day 14
Diffstat (limited to '2024')
-rw-r--r--2024/src/day14.cpp181
1 files changed, 181 insertions, 0 deletions
diff --git a/2024/src/day14.cpp b/2024/src/day14.cpp
new file mode 100644
index 0000000..97e5fab
--- /dev/null
+++ b/2024/src/day14.cpp
@@ -0,0 +1,181 @@
1#include <fstream>
2#include <iostream>
3#include <map>
4#include <regex>
5#include <set>
6#include <tuple>
7#include <vector>
8using namespace std;
9
10using pos_type = tuple<long, long>;
11using velo_type = tuple<long, long>;
12
13vector<tuple<pos_type, velo_type>>
14read_file(string_view filename)
15{
16 static const regex pattern{ R"(^p=(-?\d+),(-?\d+) v=(-?\d+),(-?\d+)$)" };
17
18 fstream input{ filename };
19
20 vector<tuple<pos_type, velo_type>> data;
21 for ( string line; getline(input, line); ) {
22 smatch matches;
23
24 if ( regex_search(line, matches, pattern) ) {
25 data.push_back({ { stoi(matches[1]), stoi(matches[2]) },
26 { stoi(matches[3]), stoi(matches[4]) } });
27 }
28 }
29 return data;
30}
31
32/*
33void
34print(const vector<tuple<pos_type, velo_type>>& robots, long width, long height)
35{
36 map<pos_type, long> map;
37
38 for ( const auto& [pos, velo]: robots ) {
39 map[pos]++;
40 }
41
42 for ( long y = 0; y != height; ++y ) {
43 for ( long x = 0; x != width; ++x ) {
44 auto pos = map.find({ x, y });
45 if ( pos != map.end() ) {
46 cout << pos->second;
47 }
48 else {
49 cout << '.';
50 }
51 }
52 cout << '\n';
53 }
54 cout << endl;
55}
56*/
57
58/*
59void
60print_pic(const vector<tuple<pos_type, velo_type>>& robots, long width, long height)
61{
62 map<pos_type, long> map;
63
64 for ( const auto& [pos, velo]: robots ) {
65 map[pos]++;
66 }
67
68 for ( long y = 0; y != height; ++y ) {
69 for ( long x = 0; x != width; ++x ) {
70 auto pos = map.find({ x, y });
71 cout << (pos != map.end() ? 'X' : ' ');
72 }
73 cout << '\n';
74 }
75 cout << endl;
76}
77*/
78
79long
80count(const vector<tuple<pos_type, velo_type>>& robots, long width, long height)
81{
82 map<pos_type, long> map;
83
84 const auto width_half = width / 2;
85 const auto height_half = height / 2;
86
87 for ( const auto& [pos, velo]: robots ) {
88 const auto [x, y] = pos;
89 if ( x == width_half || y == height_half ) {
90 continue;
91 }
92 map[{ x / (width_half + 1), y / (height_half + 1) }]++;
93 }
94
95 long result = 1;
96 for ( const auto& [pos, count]: map ) {
97 result *= count;
98 }
99 return result;
100}
101
102void
103move(vector<tuple<pos_type, velo_type>>& robots, long width, long height)
104{
105 for ( auto& [pos, velo]: robots ) {
106 auto& [x, y] = pos;
107 auto [vx, vy] = velo;
108
109 x = (x + width + vx) % width;
110 y = (y + height + vy) % height;
111 }
112}
113
114void
115part1(vector<tuple<pos_type, velo_type>> robots, long width, long height)
116{
117 for ( long second = 0; second != 100; ++second ) {
118 move(robots, width, height);
119 }
120
121 cout << count(robots, width, height) << endl;
122}
123
124void
125part2(vector<tuple<pos_type, velo_type>> robots, long width, long height)
126{
127 auto min_result = numeric_limits<long>::max();
128 long second_found = 0;
129
130 for ( long second = 0; second != 100000; ++second ) {
131 auto result = count(robots, width, height);
132
133 if ( result < min_result ) {
134 second_found = second;
135 min_result = result;
136 }
137
138 move(robots, width, height);
139 }
140 cout << second_found << endl;
141}
142
143void
144part2_alternative(vector<tuple<pos_type, velo_type>> robots, long width, long height)
145{
146 set<pos_type> seen;
147
148 for ( long second = 0; second != 100000; ++second ) {
149 seen.clear();
150
151 bool overlap = false;
152 for ( const auto& [pos, velo]: robots ) {
153 if ( seen.contains(pos) ) {
154 overlap = true;
155 break;
156 }
157 seen.insert(pos);
158 }
159
160 if ( !overlap ) {
161 cout << second << endl;
162 break;
163 }
164
165 move(robots, width, height);
166 }
167}
168
169int
170main()
171{
172#if 0
173 auto robots = read_file("data/day14-sample1.txt");
174 part1(robots, 11, 7);
175#else
176 auto robots = read_file("data/day14.txt");
177 part1(robots, 101, 103);
178 part2(robots, 101, 103);
179 part2_alternative(robots, 101, 103);
180#endif
181}