Advent of Code 2022 - 2nd attempt in c++
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

109 lines
2.2 KiB

2 years ago
#include <iostream>
#include <vector>
#include <unordered_set>
using namespace std;
enum Dir {
UP,
DOWN,
RIGHT,
LEFT
};
struct Instr {
enum Dir dir;
unsigned steps;
};
struct Pos2d {
int x, y;
Pos2d operator+(const Pos2d &r) const
{
return {this->x + r.x, this->y + r.y};
}
void operator+=(const Pos2d &r) { *this = *this + r; }
Pos2d operator-(const Pos2d &r) const
{
return {this->x - r.x, this->y - r.y};
}
bool operator==(const Pos2d &r) const
{
return this->x == r.x && this->y == r.y;
}
};
Pos2d dirs[] = {
{0, 1},
{0, -1},
{1, 0},
{-1, 0}
};
typedef vector<Instr> Input;
template<>
struct std::hash<Pos2d> {
size_t operator()(const Pos2d &r) const
{
return hash<int>{}(r.x) ^ (hash<int>{}(r.y) << 1);
}
};
Input parse()
{
Input data;
for (string line; getline(cin, line);) {
Instr instr;
if (line.size() < 3 || line.at(1) != ' ') throw "parse";
switch (line.at(0)) {
case 'U': instr.dir = UP; break;
case 'D': instr.dir = DOWN; break;
case 'L': instr.dir = LEFT; break;
case 'R': instr.dir = RIGHT; break;
}
instr.steps = stoi(line.substr(2));
data.push_back(instr);
}
return data;
}
unsigned p1(const Input &input, unsigned count = 2)
{
auto knot = vector<Pos2d>(count);
unordered_set<Pos2d> visited;
visited.insert(knot.back());
for (auto x : input) {
for (unsigned i = 0; i < x.steps; i++) {
knot.front() += dirs[x.dir];
for (auto el = knot.begin(); el < knot.end() - 1; el++) {
Pos2d dist = el[0] - el[1];
if (abs(dist.x) >= 2 || abs(dist.y) >= 2) {
if (abs(dist.x) >= 2) dist.x = dist.x > 0 ? 1 : -1;
if (abs(dist.y) >= 2) dist.y = dist.y > 0 ? 1 : -1;
el[1] += dist;
continue;
}
break;
}
visited.insert(knot.back());
}
}
return visited.size();
}
unsigned p2(const Input &input)
{
return p1(input, 10);
}
int main()
{
auto input = parse();
cout << p1(input) << endl;
cout << p2(input) << endl;
}