#include #include #include #include #include #include #include void ApplyMovement(std::pair &head, std::pair &tail) { const int x_diff = head.first - tail.first; const int y_diff = head.second - tail.second; if(std::abs(x_diff) > 1) // 2 away { tail.first += (head.first - tail.first) / 2; if(std::abs(y_diff) > 1) // 2 away due to diagonally following!!! tail.second += (head.second - tail.second) / 2; else // snap to axis since you're already on it or you're one away tail.second = head.second; } if(std::abs(y_diff) > 1) // 2 away { tail.second += (head.second - tail.second) / 2; if(std::abs(x_diff) > 1) // 2 away due to diagonally following!!! tail.first += (head.first - tail.first) / 2; else // snap to axis since you're already on it or you're one away tail.first = head.first; } } void DebugPrint(std::vector > &points, std::set > &visited_positions, std::set > &visited_positions_part2) { int x_min = points[0].first; int y_min = points[0].second; int x_max = points[0].first; int y_max = points[0].second; for(auto &pos : visited_positions) { x_min = std::min(x_min, pos.first); x_max = std::max(x_max, pos.first); y_min = std::min(y_min, pos.second); y_max = std::max(y_max, pos.second); } for(auto &pos : visited_positions_part2) { x_min = std::min(x_min, pos.first); x_max = std::max(x_max, pos.first); y_min = std::min(y_min, pos.second); y_max = std::max(y_max, pos.second); } for(auto i = 0; i < 50; ++i) std::cout << std::endl; std::cout << "X: " << x_min << " - " << x_max << std::endl; std::cout << "Y: " << y_min << " - " << y_max << std::endl; std::cout << std::endl; for(auto y = y_min; y <= y_max; ++y) { for(auto x = x_min; x <= x_max; ++x) { if(points[0].first == x && points[0].second == y) std::cout << "\033[1;30mH"; // head else if(points[1].first == x && points[1].second == y) std::cout << "\033[1;25m1"; // tail else if(points[2].first == x && points[2].second == y) std::cout << "\033[1;25m2"; // tail else if(points[3].first == x && points[3].second == y) std::cout << "\033[1;25m3"; // tail else if(points[4].first == x && points[4].second == y) std::cout << "\033[1;25m4"; // tail else if(points[5].first == x && points[5].second == y) std::cout << "\033[1;25m5"; // tail else if(points[6].first == x && points[6].second == y) std::cout << "\033[1;25m6"; // tail else if(points[7].first == x && points[7].second == y) std::cout << "\033[1;25m7"; // tail else if(points[8].first == x && points[8].second == y) std::cout << "\033[1;25m8"; // tail else if(points[9].first == x && points[9].second == y) std::cout << "\033[1;25m9"; // tail else if(visited_positions.contains({x, y})) std::cout << "\033[1;31mX"; // red else if(visited_positions_part2.contains({x, y})) std::cout << "\033[1;20mY"; // ?? else std::cout << "\033[0m-"; // default white } std::cout << std::endl; } std::cout << "\033[0m"; // default white } int main() { std::ifstream ifs("data.txt"); if(!ifs.is_open()) { std::cerr << "Missing data.txt." << std::endl; return -1; } unsigned long total = 0; unsigned long total_pt2 = 0; std::set > visited_positions; std::set > visited_positions_part2; std::vector > points; for(auto i = 0; i < 10; ++i) points.push_back({0,0}); char dir; int amt; for(std::string line; std::getline(ifs, line); ) { if(line == "") continue; dir = line[0]; amt = std::atoi(line.substr(2).c_str()); for(auto i = 0; i < amt; ++i) { // Move head: switch(dir) { case 'U': points[0].second--; break; case 'D': points[0].second++; break; case 'L': points[0].first--; break; case 'R': points[0].first++; break; } // Follow with tail: for(auto i = 0; i < points.size() - 1; ++i) ApplyMovement(points[i], points[i+1]); visited_positions.insert(points[1]); visited_positions_part2.insert(points.back()); DebugPrint(points, visited_positions, visited_positions_part2); usleep(100000); } } DebugPrint(points, visited_positions, visited_positions_part2); total = visited_positions.size(); total_pt2 = visited_positions_part2.size(); std::cout << " Total: " << total << std::endl; std::cout << "PT2 Total: " << total_pt2 << std::endl; return 0; }