-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathaoc.cpp
94 lines (74 loc) · 2.44 KB
/
aoc.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
#include <array>
#include <bitset>
#include <iostream>
#include <queue>
#include <string>
#include <tuple>
#include <vector>
using namespace std;
const int MAX_COORD = 50;
const int UNDEFINED = -1;
const int count_bits(const int n) { return bitset<32>(n).count(); }
const bool is_wall(const int x, const int y, const int favorite_number) {
if (x < 0 || y < 0) {
return true;
}
int value = x * x + 3 * x + 2 * x * y + y + y * y + favorite_number;
return count_bits(value) % 2 != 0;
}
/**
* Just here because this way we can easily test our is_wall function with the
* sample input in a visual way.
*/
const vector<string> printable_maze(const int max_x, const int max_y,
const int favorite_number) {
vector<string> maze;
for (int y = 0; y < max_y; y++) {
string row;
for (int x = 0; x < max_x; x++) {
row += is_wall(x, y, favorite_number) ? "#" : ".";
}
maze.push_back(row);
}
return maze;
}
const int total_bits(const bitset<MAX_COORD> bitsets[MAX_COORD]) {
int count = 0;
for (int i = 0; i < MAX_COORD; i++) {
count += bitsets[i].count();
}
return count;
}
const pair<int, int> flood_fill(const int target_x, const int target_y,
const int favorite_number) {
constexpr array<pair<int, int>, 4> directions = {
make_pair(0, -1), make_pair(0, 1), make_pair(-1, 0), make_pair(1, 0)};
bitset<MAX_COORD> visited[MAX_COORD];
queue<tuple<int, int, int>> queue;
queue.push(make_tuple(1, 1, 0));
int min_steps = UNDEFINED;
int visited_count = UNDEFINED;
while (!queue.empty()) {
auto [x, y, steps] = queue.front();
queue.pop();
if (steps == MAX_COORD && visited_count == UNDEFINED) {
visited_count = total_bits(visited);
}
if (x == target_x && y == target_y && min_steps == UNDEFINED) {
min_steps = steps;
}
if (min_steps != UNDEFINED && visited_count != UNDEFINED) {
return make_pair(min_steps, visited_count);
}
for (auto [dx, dy] : directions) {
int xx = x + dx;
int yy = y + dy;
if (is_wall(xx, yy, favorite_number) || visited[xx][yy]) {
continue;
}
visited[xx][yy] = true;
queue.push(make_tuple(xx, yy, steps + 1));
}
}
throw runtime_error("No path found");
}