Advent-of-Code/2022/9/main.cpp
2022-12-17 14:51:01 -05:00

170 lines
4.5 KiB
C++

#include <cmath>
#include <fstream>
#include <iostream>
#include <set>
#include <string>
#include <unistd.h>
#include <vector>
void ApplyMovement(std::pair<int, int> &head,
std::pair<int, int> &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<std::pair<int, int> > &points,
std::set<std::pair<int, int> > &visited_positions,
std::set<std::pair<int, int> > &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<std::pair<int, int> > visited_positions;
std::set<std::pair<int, int> > visited_positions_part2;
std::vector<std::pair<int, int> > 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;
}