Advertisement
Guest User

AOC 2022 Day 9 Part 2

a guest
Dec 9th, 2022
180
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 5.09 KB | Source Code | 0 0
  1. #include <algorithm>
  2. #include <cstddef>
  3. #include <cstdint>
  4. #include <cstdlib>
  5. #include <iostream>
  6. #include <fstream>
  7. #include <iterator>
  8. #include <ostream>
  9. #include <sstream>
  10. #include <string>
  11. #include <vector>
  12. #include <unordered_set>
  13.  
  14. #include "../utils/utils.hpp"   /* Used to read input file into vector */
  15.  
  16. using namespace std;
  17.  
  18. enum class Direction {
  19.     LEFT = 'L',
  20.     RIGHT = 'R',
  21.     UP = 'U',
  22.     DOWN = 'D',
  23.     UNKNOWN = '\0'
  24. };
  25.  
  26. ostream &operator<<(ostream &os, const Direction &dir) {
  27.     os << static_cast<char>(dir);
  28.     return os;
  29. }
  30.  
  31. struct Position {
  32.     int x;
  33.     int y;
  34.  
  35.     Position() : x(0), y(0) {}
  36.  
  37.     void move_position(const Direction &dir, const size_t steps) {
  38.         if (dir == Direction::LEFT)
  39.             x -= steps;
  40.         if (dir == Direction::RIGHT)
  41.             x += steps;
  42.         if (dir == Direction::UP)
  43.             y += steps;
  44.         if (dir == Direction::DOWN)
  45.             y -= steps;
  46.     }
  47.  
  48.     inline bool operator==(const Position &pos) const {
  49.         return x == pos.x && y == pos.y;
  50.     }
  51.  
  52.     struct PositionHash {
  53.         int64_t operator() (const Position &pos) const {
  54.             int32_t xHash = static_cast<int32_t>(pos.x);
  55.             int32_t yHash = static_cast<int32_t>(pos.y);
  56.             return (static_cast<int64_t>(xHash) << 32) | yHash;
  57.         }
  58.     };
  59. };
  60.  
  61. struct Rope {
  62.     Position knots[10];
  63.     Position *tail = &knots[9];
  64.     unordered_set<Position, Position::PositionHash> pos_visited_by_tail;
  65.  
  66.     void move_head(const Direction &dir, size_t steps) {
  67.         /* Move one by one */
  68.         while (steps > 0) {
  69.             Position *head = &knots[0];
  70.             head->move_position(dir, 1);
  71.             cout << "HEAD: " << head->x << ' ' << head->y << '\n';
  72.  
  73.             /* Move all the knots behind head */
  74.             for (size_t i = 1; i < 10; ++i) {
  75.                 Position *knot = &knots[i];
  76.  
  77.                 cout << "KNOT: " << knot->x << ' ' << knot->y << '\n';
  78.  
  79.                 if (head->x == knot->x || head->y == knot->y) {
  80.                     /* Head and knot in same row or col means no diagonal move */
  81.                     /* Move the knot towards the head */
  82.                     if (head->x - 1 > knot->x)
  83.                         knot->move_position(Direction::RIGHT, 1);
  84.                     else if (head->x < knot->x - 1)
  85.                         knot->move_position(Direction::LEFT, 1);
  86.                     else if (head->y - 1 > knot->y)
  87.                         knot->move_position(Direction::UP, 1);
  88.                     else if (head->y < knot->y - 1)
  89.                         knot->move_position(Direction::DOWN, 1);
  90.                 } else {
  91.                     /* Diagonal moves */
  92.                     /* Top left */
  93.                     if ((head->x == knot->x - 1 && head->y == knot->y + 2) ||
  94.                         (head->x == knot->x - 2 && head->y == knot->y + 1))
  95.                     {
  96.                         knot->move_position(Direction::LEFT, 1);
  97.                         knot->move_position(Direction::UP, 1);
  98.                     }
  99.                     /* Top right */
  100.                     else if ((head->x == knot->x + 1 && head->y == knot->y + 2) ||
  101.                              (head->x == knot->x + 2 && head->y == knot->y + 1))
  102.                     {
  103.                         knot->move_position(Direction::RIGHT, 1);
  104.                         knot->move_position(Direction::UP, 1);
  105.                     }
  106.                     /* Bottom left */
  107.                     else if ((head->x == knot->x - 2 && head->y == knot->y - 1) ||
  108.                              (head->x == knot->x - 1 && head->y == knot->y - 2))
  109.                     {
  110.                         knot->move_position(Direction::LEFT, 1);
  111.                         knot->move_position(Direction::DOWN, 1);
  112.                     }
  113.                     /* Bottom right */
  114.                     else if ((head->x == knot->x + 2 && head->y == knot->y - 1) ||
  115.                              (head->x == knot->x + 1 && head->y == knot->y - 2))
  116.                     {
  117.                         knot->move_position(Direction::RIGHT, 1);
  118.                         knot->move_position(Direction::DOWN, 1);
  119.                     }
  120.                 }
  121.  
  122.                 pos_visited_by_tail.insert(*tail);
  123.  
  124.                 head = knot;
  125.             }
  126.             cout << "-----\n";
  127.             --steps;
  128.         }
  129.     }
  130. };
  131.  
  132. Direction parse_direction(const char d) {
  133.     if (d == 'L')
  134.         return Direction::LEFT;
  135.     if (d == 'R')
  136.         return Direction::RIGHT;
  137.     if (d == 'U')
  138.         return Direction::UP;
  139.     if (d == 'D')
  140.         return Direction::DOWN;
  141.     else
  142.         return Direction::UNKNOWN;
  143. }
  144.  
  145. int main(void) {
  146.     auto input = utils::read_file("./input");
  147.     Rope rope;
  148.     int res = 0;
  149.  
  150.     for (const auto &line : input) {
  151.         auto direction = parse_direction(line[0]);
  152.         size_t steps = stoul(string{line.begin() + 2, line.end()});
  153.         rope.move_head(direction, steps);
  154.     }
  155.  
  156.     res = rope.pos_visited_by_tail.size();
  157.  
  158.     cout << "Number of visited positions of the tail: " << res << endl;
  159. }
  160.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement