+14
-17
src/07/solution.cxx
+14
-17
src/07/solution.cxx
···
3
3
#include <format>
4
4
#include <fstream>
5
5
#include <map>
6
-
#include <optional>
7
6
#include <print>
8
7
#include <string>
9
8
#include <vector>
···
86
85
};
87
86
88
87
long long count_possible_paths(std::vector<std::string> &data,
89
-
Position position, long long acc,
88
+
Position position,
90
89
std::map<std::string, long long> &cache) {
91
90
// TODO
92
-
std::optional<Position> new_pos{};
93
-
long long new_acc = acc;
94
91
if (position.y == data.size()) { // if we reached bottom
95
-
return acc + 1;
92
+
return 1;
96
93
}
94
+
long long result = 0;
97
95
if (data[position.y][position.x] == '|' ||
98
96
data[position.y][position.x] == 'S') {
99
-
new_pos = Position{.x = position.x, .y = position.y + 1};
97
+
98
+
Position new_pos{.x = position.x, .y = position.y + 1};
99
+
result = count_possible_paths(data, new_pos, cache);
100
+
100
101
} else if (data[position.y][position.x] == '^') {
101
102
Position left = Position{.x = position.x - 1, .y = position.y};
102
103
Position right = Position{.x = position.x + 1, .y = position.y};
103
104
104
105
// a weird workaround to satisfy some static checks. maps must be sortable.
105
106
if (cache.contains(position.encode())) {
106
-
new_acc = cache[position.encode()];
107
+
result = cache[position.encode()];
107
108
} else {
108
-
new_acc = count_possible_paths(data, left, 0, cache) +
109
-
count_possible_paths(data, right, 0, cache);
109
+
result = count_possible_paths(data, left, cache) +
110
+
count_possible_paths(data, right, cache);
110
111
111
-
cache[position.encode()] = new_acc;
112
+
cache[position.encode()] = result;
112
113
}
113
114
}
114
115
115
-
if (!new_pos.has_value()) {
116
-
return new_acc;
117
-
}
118
-
__attribute__((musttail)) return count_possible_paths(data, new_pos.value(),
119
-
new_acc, cache);
116
+
return result;
120
117
}
121
118
122
119
long long count_possible_paths(std::vector<std::string> &data,
···
125
122
.x = data[0].find_first_of('S'),
126
123
.y = 0,
127
124
};
128
-
return count_possible_paths(data, start, 1, cache);
125
+
return count_possible_paths(data, start, cache);
129
126
}
130
127
131
-
// runtime on Ryzen 5 5600G: 0.018s
128
+
// runtime on Ryzen 5 5600G: 0.004s
132
129
int main() {
133
130
auto data_path = get_input_path(DATA_FOLDER);
134
131
std::ifstream data_ifstream(data_path);