#include #include #include #include #include #include using namespace std; void parseGrid(const char *path, vector> &grid) { ifstream input(path); string line; while (getline(input, line)) { stringstream line_stream; line_stream << line; vector line_vec; char c; while (line_stream >> c) { line_vec.push_back(c); } grid.push_back(line_vec); } } void printGrid(vector> grid) { for (int y = 0; y < grid.size(); y++) { for (int x = 0; x < grid[0].size(); x++) { cout << grid[y][x] << " "; } cout << endl; } } // do one move and save new position in x and y // returns false if the guard left the grid. bool move(vector> &grid, int &x_ret, int &y_ret, char &c) { for (int y = 0; y < grid.size(); y++) { for (int x = 0; x < grid[y].size(); x++) { if (grid[y][x] == 'v') { // cout << "down" << endl; if (y == grid.size() - 1) { grid[y][x] = '.'; x_ret = x; y_ret = y; c = 'v'; return true; } if (grid[y + 1][x] == '#') { grid[y][x] = '<'; x_ret = x; y_ret = y; c = 'v'; return true; } grid[y][x] = '.'; grid[y + 1][x] = 'v'; c = 'v'; x_ret = x; y_ret = y; return true; } else if (grid[y][x] == '^') { // cout << "up" << endl; if (y == 0) { grid[y][x] = '.'; c = '^'; x_ret = x; y_ret = y; return true; } if (grid[y - 1][x] == '#') { grid[y][x] = '>'; c = '^'; x_ret = x; y_ret = y; return true; } grid[y][x] = '.'; grid[y - 1][x] = '^'; c = '^'; x_ret = x; y_ret = y; return true; } else if (grid[y][x] == '>') { // cout << "right" << endl; if (x == grid[y].size() - 1) { grid[y][x] = '.'; x_ret = x; y_ret = y; c = '>'; return true; } if (grid[y][x + 1] == '#') { grid[y][x] = 'v'; c = '>'; x_ret = x; y_ret = y; return true; } grid[y][x] = '.'; grid[y][x + 1] = '>'; c = '>'; x_ret = x; y_ret = y; return true; } else if (grid[y][x] == '<') { // cout << "left" << endl; if (x == 0) { grid[y][x] = '.'; x_ret = x; y_ret = y; c = '<'; return true; } if (grid[y][x - 1] == '#') { grid[y][x] = '^'; c = '<'; x_ret = x; y_ret = y; return true; } grid[y][x] = '.'; grid[y][x - 1] = '<'; c = '<'; x_ret = x; y_ret = y; return true; } } } return false; } void part1(const char *path) { vector> grid; int x; int y; char c; parseGrid(path, grid); set> visited[grid.size()][grid[0].size()]; // initialize vector for (int y = 0; y < grid.size(); y++) { for (int x = 0; x < grid[0].size(); x++) { set> s; visited[y][x] = s; } } int sum = 0; while (move(grid, x, y, c)) { if (!visited[y][x].size()) { sum++; visited[y][x].insert(c); } } cout << path << "1: " << sum << endl; } bool has_loop(vector> grid) { // printGrid(grid); int x; int y; char c; set> visited[grid.size()][grid[0].size()]; // initialize vector for (int y = 0; y < grid.size(); y++) { for (int x = 0; x < grid[0].size(); x++) { set> s; visited[y][x] = s; } } while (move(grid, x, y, c)) { // cout << endl; // printGrid(grid); if (visited[y][x].count(c)) { return true; } visited[y][x].insert(c); } return false; } void part2(const char *path) { vector> grid; parseGrid(path, grid); int sum = 0; for (int y = 0; y < grid.size(); y++) { for (int x = 0; x < grid[0].size(); x++) { // cout << "x= " << x << " y= " << y << endl; if (grid[y][x] == '.') { grid[y][x] = '#'; // cout << "before has_loop" << endl; if (has_loop(grid)) sum++; // cout << "after has_loop" << sum << endl; grid[y][x] = '.'; } } } cout << path << "2: " << sum << endl; } int main(int argc, char *argv[]) { part1("example"); part1("input"); part2("example"); part2("input"); return 0; }