advent_of_code/2022/09/main.cpp

124 lines
3.0 KiB
C++
Raw Normal View History

2022-12-09 18:44:28 +00:00
#include <fstream>
#include <iostream>
#include <sstream>
#include <vector>
#include <unordered_map>
enum Directions {
UP,
DOWN,
LEFT,
RIGHT
};
struct Command {
Directions direction;
int steps;
};
struct Position {
int x;
int y;
};
Directions charToDirection(char c) {
switch(c) {
case 'R':
return RIGHT;
case 'L':
return LEFT;
case 'U':
return UP;
case 'D':
return DOWN;
}
std::cerr << "Invalid direction" << std::endl;
exit(1);
}
std::vector<Command> getCommands( std::ifstream &file ) {
std::vector<Command> ret{};
int tmp_i = 0;
char tmp_c = 0;
std::string str;
while ( std::getline( file, str ) ) {
std::stringstream ss( str );
ss >> tmp_c;
ss >> tmp_i;
ret.push_back({charToDirection(tmp_c), tmp_i});
}
return ret;
}
void handleMovement(const Position &head, Position &tail) {
auto x_diff = head.x - tail.x;
auto y_diff = head.y - tail.y;
if(abs(x_diff) > 1 || abs(y_diff) > 1) {
if(x_diff != 0) {
x_diff /= abs(x_diff);
}
if(y_diff != 0) {
y_diff /= abs(y_diff);
}
tail.x += x_diff;
tail.y += y_diff;
}
}
int ropeSimulation(const std::vector<Command> &commands, int rope_length) {
std::vector<Position> positions;
positions.resize(rope_length);
for(int i = 0; i < rope_length; i++) {
positions[i] = {0, 0};
}
std::unordered_map<int, std::unordered_map<int, bool>> visits{};
visits[0][0] = true;
for(auto &command : commands) {
Position addition{0, 0};
switch(command.direction) {
case RIGHT:
addition = {1, 0};
break;
case LEFT:
addition = {-1, 0};
break;
case UP:
addition = {0, -1};
break;
case DOWN:
addition = {0, 1};
break;
}
for(int i = 0; i < command.steps; i++) {
positions[0].x += addition.x;
positions[0].y += addition.y;
for(int i = 1; i < rope_length; i++) {
handleMovement(positions[i-1], positions[i]);
}
visits[positions.back().x][positions.back().y] = true;
}
}
int result = 0;
for(auto &visit : visits) {
result += visit.second.size();
}
return result;
}
int part1(const std::vector<Command> &commands) {
return ropeSimulation(commands, 2);
}
int part2(const std::vector<Command> &commands) {
return ropeSimulation(commands, 10);
}
int main() {
std::ifstream input_file( "input" );
auto commands = getCommands( input_file );
std::cout << "The rope's tail visits \033[91;1m" << part1(commands)
<< "\033[0m positions." << std::endl;
std::cout << "The long rope's tail visits \033[91;1m" << part2(commands)
<< "\033[0m positions." << std::endl;
}