-
Notifications
You must be signed in to change notification settings - Fork 0
/
12.cpp
119 lines (90 loc) · 2.45 KB
/
12.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
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
#include <fstream>
#include <iostream>
#include <queue>
#include <utility>
#include <vector>
#include <fmt/core.h>
#include <fmt/ranges.h>
typedef std::pair<int, int> pos;
int solution(std::vector<std::string> data, pos start,
std::function<bool(pos)> done,
std::function<bool(char, char)> nogo) {
int max_x = data[0].size() - 1;
int max_y = data.size() - 1;
bool visited[data.size()][data[0].size()];
std::fill_n(&visited[0][0], sizeof(visited) / sizeof(**visited), false);
std::queue<std::vector<pos>> q{};
std::vector<pos> s{};
s.push_back(start);
q.push(s);
bool found = false;
while (!q.empty()) {
auto n = q.front();
q.pop();
auto cur = n.back();
// fmt::print("{}\n", fmt::join(n, ">"));
char c = data[cur.second][cur.first];
std::vector<pos> neighbours{
{cur.first - 1, cur.second},
{cur.first + 1, cur.second},
{cur.first, cur.second - 1},
{cur.first, cur.second + 1},
};
for (auto ngb : neighbours) {
int nx = ngb.first;
int ny = ngb.second;
if (visited[ny][nx] || nx < 0 || nx > max_x || ny < 0 || ny > max_y)
continue;
char nc = data[ny][nx];
if (nogo(nc, c))
continue;
auto ns = n;
ns.push_back({nx, ny});
q.push(ns);
visited[ny][nx] = true;
if (done(pos{nx, ny})) {
found = true;
break;
}
}
if (found) break;
}
/*
for (auto p: q.back()) {
std::cout << data[p.second][p.first] << fmt::format("{} ", p);
}
std::cout << std::endl;
*/
return q.back().size() - 1;
}
int main(int argc, char *argv[]) {
if (argc < 2) {
return 1;
}
std::ifstream file(argv[1]);
pos start, stop;
int y = 0;
std::vector<std::string> data;
for (std::string line; std::getline(file, line);) {
for (int x = 0; x < line.size(); ++x) {
if (line[x] == 'S') {
start = {x, y};
line[x] = 'a';
} else if (line[x] == 'E') {
stop = {x, y};
line[x] = 'z';
}
}
data.push_back(line);
y++;
}
// fmt::print("{}\n", fmt::join(data, "\n"));
int first = solution(
data, start, [&](pos x) { return x == stop; },
[](char nc, char c) { return nc - 1 > c; });
int second = solution(
data, stop, [&](pos x) { return data[x.second][x.first] == 'a'; },
[](char nc, char c) { return nc + 1 < c; });
std::cout << first << std::endl;
std::cout << second << std::endl;
}