#include #include #include 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 Input; template<> struct std::hash { size_t operator()(const Pos2d &r) const { return hash{}(r.x) ^ (hash{}(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(count); unordered_set 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; }