138 lines
3 KiB
C++
138 lines
3 KiB
C++
#include <fstream>
|
|
#include <iostream>
|
|
#include <sstream>
|
|
#include <vector>
|
|
#include <tuple>
|
|
#include <set>
|
|
|
|
using namespace std;
|
|
|
|
vector<vector<int>> parseGrid(const char *path) {
|
|
vector<vector<int>> grid;
|
|
|
|
ifstream input(path);
|
|
string line;
|
|
while (getline(input, line)) {
|
|
char c;
|
|
vector<int> row;
|
|
stringstream ss;
|
|
ss << line;
|
|
while (ss >> c) {
|
|
int num = c - '0';
|
|
row.push_back(num);
|
|
}
|
|
grid.push_back(row);
|
|
}
|
|
return grid;
|
|
}
|
|
|
|
void printGrid(vector<vector<int>> grid) {
|
|
for (int y = 0; y < grid.size(); y++) {
|
|
for (int x = 0; x < grid[0].size(); x++) {
|
|
cout << grid[y][x];
|
|
}
|
|
cout << endl;
|
|
}
|
|
}
|
|
|
|
int trailheadHelper(vector<vector<int>> grid, int y, int x, set<tuple<int,int>, greater<tuple<int,int>>> &visited) {
|
|
int curr = grid[y][x];
|
|
|
|
// base case
|
|
if (curr == 9) {
|
|
if (visited.count(make_tuple(y,x))) {
|
|
return 0;
|
|
} else {
|
|
visited.insert(make_tuple(y,x));
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
int sum = 0;
|
|
|
|
// try each direction
|
|
if (x > 0 && grid[y][x - 1] == grid[y][x] + 1) {
|
|
sum += trailheadHelper(grid, y, x - 1, visited);
|
|
}
|
|
if (x < grid[y].size() - 1 && grid[y][x + 1] == grid[y][x] + 1) {
|
|
sum += trailheadHelper(grid, y, x + 1, visited);
|
|
}
|
|
if (y > 0 && grid[y - 1][x] == grid[y][x] + 1) {
|
|
sum += trailheadHelper(grid, y - 1, x, visited);
|
|
}
|
|
if (y < grid.size() - 1 && grid[y + 1][x] == grid[y][x] + 1) {
|
|
sum += trailheadHelper(grid, y + 1, x, visited);
|
|
}
|
|
|
|
return sum;
|
|
}
|
|
|
|
int trailheadCount(vector<vector<int>> grid, int y, int x) {
|
|
set<tuple<int,int>, greater<tuple<int,int>>> visited;
|
|
|
|
return trailheadHelper(grid, y, x, visited);
|
|
}
|
|
|
|
int trailheadCount2(vector<vector<int>> grid, int y, int x) {
|
|
int curr = grid[y][x];
|
|
|
|
// base case
|
|
if (curr == 9) {
|
|
return 1;
|
|
}
|
|
|
|
int sum = 0;
|
|
|
|
// try each direction
|
|
if (x > 0 && grid[y][x - 1] == grid[y][x] + 1) {
|
|
sum += trailheadCount2(grid, y, x - 1);
|
|
}
|
|
if (x < grid[y].size() - 1 && grid[y][x + 1] == grid[y][x] + 1) {
|
|
sum += trailheadCount2(grid, y, x + 1);
|
|
}
|
|
if (y > 0 && grid[y - 1][x] == grid[y][x] + 1) {
|
|
sum += trailheadCount2(grid, y - 1, x);
|
|
}
|
|
if (y < grid.size() - 1 && grid[y + 1][x] == grid[y][x] + 1) {
|
|
sum += trailheadCount2(grid, y + 1, x);
|
|
}
|
|
|
|
return sum;
|
|
}
|
|
|
|
|
|
int part1(const char *path) {
|
|
vector<vector<int>> grid = parseGrid(path);
|
|
|
|
int sum = 0;
|
|
for (int y = 0; y < grid.size(); y++) {
|
|
for (int x = 0; x < grid[0].size(); x++) {
|
|
if (grid[y][x] == 0) {
|
|
sum += trailheadCount(grid, y, x);
|
|
}
|
|
}
|
|
}
|
|
return sum;
|
|
}
|
|
|
|
int part2(const char *path) {
|
|
vector<vector<int>> grid = parseGrid(path);
|
|
|
|
int sum = 0;
|
|
for (int y = 0; y < grid.size(); y++) {
|
|
for (int x = 0; x < grid[0].size(); x++) {
|
|
if (grid[y][x] == 0) {
|
|
sum += trailheadCount2(grid, y, x);
|
|
}
|
|
}
|
|
}
|
|
return sum;
|
|
}
|
|
|
|
int main(int argc, char *argv[]) {
|
|
cout << "example1: " << part1("example") << endl;
|
|
cout << "input1: " << part1("input") << endl;
|
|
cout << "example2: " << part2("example") << endl;
|
|
cout << "input2: " << part2("input") << endl;
|
|
return 0;
|
|
}
|