mid-kid
2 years ago
3 changed files with 2110 additions and 0 deletions
@ -0,0 +1,108 @@ |
|||||
|
#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; |
||||
|
} |
File diff suppressed because it is too large
@ -0,0 +1,2 @@ |
|||||
|
5930 |
||||
|
2443 |
Loading…
Reference in new issue