aboutsummaryrefslogtreecommitdiff
path: root/2024
diff options
context:
space:
mode:
Diffstat (limited to '2024')
-rw-r--r--2024/src/day18-opti.cpp115
1 files changed, 115 insertions, 0 deletions
diff --git a/2024/src/day18-opti.cpp b/2024/src/day18-opti.cpp
new file mode 100644
index 0000000..67374fe
--- /dev/null
+++ b/2024/src/day18-opti.cpp
@@ -0,0 +1,115 @@
1#include <fstream>
2#include <iostream>
3#include <queue>
4#include <set>
5#include <sstream>
6#include <string>
7#include <tuple>
8#include <vector>
9using namespace std;
10
11using pos_type = tuple<long, long>;
12
13vector<pos_type>
14read_file(string_view filename)
15{
16 fstream input{ filename };
17 vector<pos_type> data;
18
19 long lhs = 0;
20 long rhs = 0;
21 char chr = 0;
22
23 while ( input >> lhs >> chr >> rhs ) {
24 data.emplace_back(lhs, rhs);
25 }
26 return data;
27}
28
29optional<long>
30bfs(const vector<pos_type>& data, long size)
31{
32 set<pos_type> stones{ data.begin(), data.end() };
33
34 set<pos_type> seen;
35
36 // x, y, distance
37 queue<tuple<pos_type, long>> queue;
38 queue.push({ { 0, 0 }, 0 });
39
40 while ( !queue.empty() ) {
41 const auto& [pos, distance] = queue.front();
42 queue.pop();
43
44 const auto [x, y] = pos;
45
46 if ( x == size && y == size ) {
47 return distance;
48 }
49
50 if ( x < 0 || y < 0 || x > size || y > size ) {
51 continue;
52 }
53
54 if ( stones.contains(pos) ) {
55 continue;
56 }
57
58 if ( seen.contains(pos) ) {
59 continue;
60 }
61 seen.insert(pos);
62
63 for ( const auto& [nx, ny]: vector<pos_type>{ { x - 1, y }, { x + 1, y }, { x, y - 1 }, { x, y + 1 } } ) {
64 queue.push({ { nx, ny }, distance + 1 });
65 }
66 }
67 return nullopt;
68}
69
70void
71part1(const vector<pos_type>& data, long size)
72{
73 if ( auto result = bfs(data, size) ) {
74 cout << *result << endl;
75 }
76}
77
78void
79part2(const vector<pos_type>& data, long size)
80{
81 size_t lhs = 0;
82 size_t rhs = data.size() - 1;
83
84 while ( lhs < rhs ) {
85 auto mid = lhs + (rhs - lhs) / 2;
86
87 if ( bfs({ data.begin(), data.begin() + ptrdiff_t(mid + 1) }, size) ) {
88 lhs = mid + 1;
89 }
90 else {
91 rhs = mid;
92 }
93 }
94
95 const auto& [x, y] = data[lhs];
96 cout << x << "," << y << endl;
97}
98
99int
100main()
101{
102#if 0
103 const auto data = read_file("data/day18-sample1.txt");
104 const long size = 6;
105
106 part1({ data.begin(), data.begin() + 12 }, size);
107 part2(data, size);
108#else
109 const auto data = read_file("data/day18.txt");
110 const long size = 70;
111
112 part1({ data.begin(), data.begin() + 1024 }, size);
113 part2(data, size);
114#endif
115}