advent-of-code/2023/10/main-2.cpp
2023-12-09 23:40:44 -08:00

151 lines
2.7 KiB
C++

#include <bits/stdc++.h>
using namespace std;
vector<string> lines;
#define R(x, y) rets.push_back(make_pair(r + x, c + y))
vector<pair<int, int>> findcons(int r, int c) {
vector<pair<int, int>> rets;
switch (lines[r][c]) {
case '|':
R(-1, 0);
R(1, 0);
break;
case '-':
R(0, -1);
R(0, 1);
break;
case 'L':
R(-1, 0);
R(0, 1);
break;
case 'J':
R(-1, 0);
R(0, -1);
break;
case '7':
R(1, 0);
R(0, -1);
break;
case 'F':
R(1, 0);
R(0, 1);
break;
case 'S':
for (int rr = -1; rr <= 1; rr++) {
for (int cc = -1; cc <= 1; cc++) {
if (rr == 0 && cc == 0)
continue;
unsigned int rrr = r + rr, ccc = c + cc;
if ((int)rrr < 0 || rrr == lines.size() || (int)ccc < 0 || ccc == lines[rrr].size())
continue;
for (auto& con : findcons(rrr, ccc)) {
if (con.first == r && con.second == c) {
R(rr, cc);
goto lend;
}
}
}
}
lend:
break;
}
return rets;
}
#undef R
int main() {
ios::sync_with_stdio(0);
cin.tie(0);
string line;
while (getline(cin, line) && !line.empty()) {
lines.push_back(line);
}
int sr = 0, sc = 0;
for (unsigned int rr = 0; rr < lines.size(); rr++) {
for (unsigned int cc = 0; cc < lines[rr].size(); cc++) {
if (lines[rr][cc] == 'S') {
sr = rr;
sc = cc;
goto lend;
}
}
}
lend:
const auto& scons = findcons(sr, sc);
int lr = sr, lc = sc, r = scons[0].first, c = scons[0].second;
bool path[lines.size()][lines[0].size()];
memset(path, 0, lines.size() * lines[0].size() * sizeof(bool));
path[r][c] = true;
bool others[3][3] = {};
others[r - sr + 1][c - sc + 1] = true;
do {
for (auto& con : findcons(r, c)) {
if (con.first == lr && con.second == lc)
continue;
lr = r;
lc = c;
r = con.first;
c = con.second;
path[r][c] = true;
break;
}
} while (r != sr || c != sc);
others[lr - sr + 1][lc - sc + 1] = true;
int ret = 0;
for (unsigned int r = 0; r < lines.size(); r++) {
bool inside = false;
char le = '\0';
for (unsigned int c = 0; c < lines[r].size(); c++) {
if (path[r][c]) {
char ch = lines[r][c];
sstart:
switch (ch) {
case 'S':
if (others[1][2]) {
if (others[1][0])
break;
if (others[0][1]) {
ch = 'L';
} else {
ch = 'F';
}
} else if (others[1][0]) {
if (others[0][1]) {
ch = 'J';
} else {
ch = '7';
}
} else {
ch = '|';
}
goto sstart;
case 'L':
case 'F':
le = ch;
break;
case 'J':
case '7':
if ((le == 'L' && ch == 'J') || (le == 'F' && ch == '7'))
break;
// fallthrough
case '|':
inside = !inside;
break;
}
} else if (inside) {
ret++;
}
}
}
cout << ret << '\n';
}