Skip to content

Commit 33706fb

Browse files
author
Christian Lundh
committed
C++23 2024 day 6 (Update) Still too slow
1 parent f286093 commit 33706fb

File tree

1 file changed

+61
-36
lines changed

1 file changed

+61
-36
lines changed

C++/2024/aoc_2024_06.cpp

Lines changed: 61 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -8,23 +8,47 @@
88
#include <unordered_set>
99
#include <vector>
1010

11-
using Position = std::pair<int, int>;
12-
using Direction = std::pair<int, int>;
11+
// using Position = std::pair<int, int>;
12+
// using Direction = std::pair<int, int>;
13+
14+
template <class T>
15+
struct Position : std::pair<T, T> {
16+
Position() {
17+
this->first = 0;
18+
this->second = 0;
19+
}
20+
Position(T x, T y) {
21+
this->first = x;
22+
this->second = y;
23+
}
24+
Position operator+(const Position &p2) {
25+
return {this->first + p2.first, this->second + p2.second};
26+
}
27+
Position &operator+=(const Position &rhs) {
28+
this->first += rhs.first;
29+
this->second += rhs.second;
30+
return *this;
31+
}
32+
};
1333

14-
template <>
15-
struct std::hash<Position> {
16-
auto operator()(const Position &v) const -> size_t {
34+
template <class T>
35+
using Direction = Position<T>;
36+
37+
template <class T>
38+
struct std::hash<Position<T>> {
39+
auto operator()(const Position<T> &v) const -> size_t {
1740
return size_t(v.first) << 32 | v.second;
1841
}
1942
};
2043

21-
template <>
22-
struct std::hash<std::pair<Position, Direction>> {
23-
auto operator()(const std::pair<Position, Direction> &v) const -> size_t {
24-
return std::hash<Position>()(v.first) ^ std::hash<Direction>()(v.second);
44+
template <class T>
45+
struct std::hash<std::pair<Position<T>, Position<T>>> {
46+
auto operator()(const std::pair<Position<T>, Direction<T>> &v) const -> size_t {
47+
return std::hash<Position<T>>()(v.first) ^ std::hash<Direction<T>>()(v.second);
2548
}
2649
};
2750

51+
template <class T>
2852
struct Map {
2953
Map() = delete;
3054

@@ -33,34 +57,34 @@ struct Map {
3357
visited.insert(guard_position);
3458
}
3559

36-
[[nodiscard]] Position guard() const {
60+
[[nodiscard]] auto guard() const -> Position<T> {
3761
return guard_position;
3862
}
3963

40-
[[nodiscard]] auto &get_visited() {
64+
[[nodiscard]] auto get_visited() -> auto & {
4165
return visited;
4266
}
4367

44-
int get_visited_size() const {
68+
[[nodiscard]] auto get_visited_size() const -> int {
4569
return int(visited.size());
4670
}
4771

48-
char get_location(const Position &position) const {
72+
[[nodiscard]] auto get_location(const Position<T> &position) const -> char {
4973
const auto &[col, row] = position;
5074
if (is_inside(position))
5175
return contents[row][col];
5276
else
5377
return '\0';
5478
}
5579

56-
bool is_inside(const Position &position) const {
80+
[[nodiscard]] auto is_inside(const Position<T> &position) const -> bool {
5781
return ((position.first >= 0) && (position.first < int(contents.front().size()))) && ((position.second >= 0) && (position.second < int(contents.size())));
5882
}
5983

6084
private:
61-
std::vector<std::string> contents;
62-
Position guard_position;
63-
std::unordered_set<Position> visited;
85+
std::vector<std::string> contents;
86+
Position<T> guard_position;
87+
std::unordered_set<Position<T>> visited;
6488

6589
void find_guard() {
6690
int x{}, y{};
@@ -75,32 +99,30 @@ struct Map {
7599
}
76100
};
77101

78-
Position operator+(const Position &p1, const Direction &p2) {
79-
return {p1.first + p2.first, p1.second + p2.second};
80-
}
81-
82-
void turn(std::array<std::pair<int, int>, 4> &directions) {
102+
template <class T>
103+
void turn(std::array<Direction<T>, 4> &directions) {
83104
std::ranges::rotate(directions, directions.end() - 1);
84105
}
85106

86-
void print_position(const Position &p) {
107+
void print_position(const auto &p) {
87108
std::cout << "[" << p.first << ", " << p.second << "]\n";
88109
}
89110

90-
std::array<Direction, 4> init_directions() {
91-
std::array<Direction, 4> directions{
111+
template <class T>
112+
auto init_directions() -> std::array<Direction<T>, 4> {
113+
std::array<Direction<T>, 4> directions{
92114
{{0, -1}, {-1, 0}, {0, 1}, {1, 0}}
93115
};
94116
return directions;
95117
}
96118

97-
auto parse_instructions(const std::vector<std::string> &instructions) -> Map {
98-
auto map = Map{instructions};
119+
auto parse_instructions(const std::vector<std::string> &instructions) -> Map<int> {
120+
auto map = Map<int>{instructions};
99121
return map;
100122
}
101123

102-
auto solve_part_1(Map &map) -> int {
103-
auto directions = init_directions();
124+
auto solve_part_1(Map<int> &map) -> int {
125+
auto directions = init_directions<int>();
104126
auto guard_position = map.guard();
105127
auto &visited = map.get_visited();
106128

@@ -118,26 +140,29 @@ auto solve_part_1(Map &map) -> int {
118140
return map.get_visited_size();
119141
}
120142

121-
auto solve_part_2(Map &map) -> int {
143+
auto solve_part_2(Map<int> &map) -> int {
122144
auto guard_position = map.guard();
123145
auto &visited = map.get_visited();
124146

125147
auto count = 0;
126148

149+
visited.erase(guard_position);
150+
127151
for (const auto &obstacle : visited) {
128-
auto directions = init_directions();
152+
auto directions = init_directions<int>();
129153
guard_position = map.guard();
130-
std::unordered_set<std::pair<Position, Direction>> tracemap{
154+
std::unordered_set<std::pair<Position<int>, Direction<int>>> tracemap{
131155
{guard_position, directions.front()}
132156
};
133157

134-
if (obstacle == guard_position)
135-
continue;
158+
// if (obstacle == guard_position)
159+
// continue;
136160

161+
Position<int> next_position{};
137162
tracemap.insert({guard_position, directions.front()});
138163
while (true) {
139-
Position next_position = guard_position + directions.front();
140-
auto c = map.get_location(next_position);
164+
next_position = guard_position + directions.front();
165+
auto c = map.get_location(next_position);
141166
if (c == '\0') {
142167
break;
143168
} else if ((c == '#') || (next_position == obstacle)) {

0 commit comments

Comments
 (0)