2024 day 16

This commit is contained in:
eriedaberrie 2024-12-16 01:18:23 -08:00
parent 456cf1ef3f
commit 8b47a9d0f8
2 changed files with 182 additions and 0 deletions

71
2024/16/main-1.cpp Normal file
View file

@ -0,0 +1,71 @@
#include <bits/stdc++.h>
#include "../../include/aoc.hpp"
using namespace std;
unordered_map<Coord<int>, unordered_map<int, int>> m;
inline Coord<int> posdir(int p) {
switch (p) {
case 0:
return {0, 1};
case 1:
return {1, 0};
case 2:
return {0, -1};
case 3:
return {-1, 0};
default:
return {};
}
}
void rec(Coord<int> pos, int dir, int score) {
if (!m.contains(pos)) {
return;
}
auto &mp = m[pos];
if (mp.contains(dir) && mp[dir] <= score) {
return;
}
mp[dir] = score;
rec(pos + posdir(dir), dir, score + 1);
rec(pos, (dir + 1) & 3, score + 1000);
rec(pos, (dir - 1) & 3, score + 1000);
}
int main() {
ios::sync_with_stdio(0);
cin.tie(0);
Coord<int> pos, s, e;
string line;
while (getline(cin, line) && !line.empty()) {
for (pos.y = 0; pos.y < line.size(); pos.y++) {
switch (line[pos.y]) {
case '#':
continue;
case 'S':
s = pos;
break;
case 'E':
e = pos;
break;
}
m[pos];
}
pos.x++;
}
rec(s, 0, 0);
int minscore = -1;
for (auto [dir, score] : m[e]) {
if (minscore == -1 || score < minscore) {
minscore = score;
}
}
cout << minscore << '\n';
}

111
2024/16/main-2.cpp Normal file
View file

@ -0,0 +1,111 @@
#include <bits/stdc++.h>
#include "../../include/aoc.hpp"
using namespace std;
unordered_map<Coord<int>, unordered_map<int, pair<int, set<int>>>> m;
inline Coord<int> posdir(int p) {
switch (p) {
case 0:
return {0, 1};
case 1:
return {1, 0};
case 2:
return {0, -1};
case 3:
return {-1, 0};
default:
return {};
}
}
void rec(Coord<int> pos, int dir, int score, int follow) {
if (!m.contains(pos)) {
return;
}
auto &mp = m[pos];
if (mp.contains(dir)) {
auto &[s, f] = mp[dir];
if (s < score) {
return;
}
if (s > score) {
f.clear();
}
f.insert(follow);
if (s == score) {
return;
}
s = score;
} else {
mp[dir] = {score, {follow}};
}
mp[dir].second.insert(follow);
rec(pos + posdir(dir), dir, score + 1, dir);
rec(pos, (dir + 1) & 3, score + 1000, follow);
rec(pos, (dir - 1) & 3, score + 1000, follow);
}
void rec2(unordered_set<Coord<int>> &mm, Coord<int> pos, int dir) {
mm.insert(pos);
auto &[s, f] = m[pos][dir];
for (auto follow : f) {
if (follow == -1) {
continue;
}
rec2(mm, pos + posdir((follow + 2) & 3), follow);
}
}
int main() {
ios::sync_with_stdio(0);
cin.tie(0);
Coord<int> pos, s, e;
string line;
while (getline(cin, line) && !line.empty()) {
for (pos.y = 0; pos.y < line.size(); pos.y++) {
switch (line[pos.y]) {
case '#':
continue;
case 'S':
s = pos;
break;
case 'E':
e = pos;
break;
}
m[pos];
}
pos.x++;
}
rec(s, 0, 0, -1);
int minscore = -1;
vector<int> dirs;
for (auto &[dir, sf] : m[e]) {
auto &[s, f] = sf;
if (minscore == -1 || s < minscore) {
minscore = s;
dirs.clear();
} else if (s > minscore) {
continue;
}
dirs.push_back(dir);
}
unordered_set<Coord<int>> mm;
for (auto dir : dirs) {
rec2(mm, e, dir);
}
cout << mm.size() << '\n';
}