#include #include #include #include #include long ScenicScore(int set_x, int set_y, std::vector> &trees) { const int tree_val = trees[set_y][set_x]; int score_up = 0; int score_down = 0; int score_left = 0; int score_right = 0; // up for(int y = set_y - 1; y >= 0; --y) { ++score_up; if(trees[y][set_x] >= tree_val) break; } // down for(int y = set_y + 1; y < trees.size(); ++y) { ++score_down; if(trees[y][set_x] >= tree_val) break; } // left for(int x = set_x - 1; x >= 0; --x) { ++score_left; if(trees[set_y][x] >= tree_val) break; } // right for(int x = set_x + 1; x < trees[set_y].size(); ++x) { ++score_right; if(trees[set_y][x] >= tree_val) break; } return score_up * score_down * score_left * score_right; } 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::vector> trees; // Parse: for(std::string line; std::getline(ifs, line); ) { if(line == "") continue; trees.push_back({}); for(const char &ch : line) trees.back().push_back(ch - '0'); } std::set> visible_coordinates; for(auto y = 0; y < trees.size(); ++y) { visible_coordinates.insert({0,y}); visible_coordinates.insert({trees[y].size()-1,y}); } for(auto x = 1; x < trees[0].size() - 1; ++x) { visible_coordinates.insert({x,0}); visible_coordinates.insert({x,trees.size()-1}); } // left to right, right to left IN EACH ROW: std::vector points; for(auto y = 1; y < trees.size() - 1; ++y) { points.clear(); // initialize list with the first value points.push_back(trees[y][0]); // iterate through the rest: for(auto x = 1; x < trees[y].size(); ++x) { // if it's higher than the most recent one: const auto val = trees[y][x]; if(val > points.back()) { points.push_back(val); visible_coordinates.insert({x,y}); } } } for(auto y = 1; y < trees.size() - 1; ++y) { points.clear(); // initialize list with the first value points.push_back(trees[y][trees.size()-1]); // iterate through the rest: for(auto x = trees[y].size() - 2; x > 0; --x) { // if it's higher than the most recent one: const auto val = trees[y][x]; if(val > points.back()) { points.push_back(val); visible_coordinates.insert({x,y}); } } } for(auto x = 1; x < trees[0].size() - 1; ++x) { points.clear(); // initialize list with the first value points.push_back(trees[0][x]); // iterate through the rest: for(auto y = 1; y < trees.size(); ++y) { // if it's higher than the most recent one: const auto val = trees[y][x]; if(val > points.back()) { points.push_back(val); visible_coordinates.insert({x,y}); } } } for(auto x = 1; x < trees[0].size() - 1; ++x) { points.clear(); // initialize list with the first value points.push_back(trees[trees.size()-1][x]); // iterate through the rest: for(auto y = trees.size()-2; y > 0; --y) { // if it's higher than the most recent one: const auto val = trees[y][x]; if(val > points.back()) { points.push_back(val); visible_coordinates.insert({x,y}); } } } total += visible_coordinates.size(); for(auto y = 0; y < trees.size(); ++y) { for(auto x = 0; x < trees[y].size(); ++x) { if(visible_coordinates.contains({x,y})) std::cout << "\033[1;31m"; // red else std::cout << "\033[0m"; // default white std::cout << trees[y][x]; } std::cout << std::endl; } std::cout << "\033[0m"; // default white std::cout << " Total: " << total << std::endl; long highest_scenic = 0; for(auto y = 0; y < trees.size(); ++y) { for(auto x = 0; x < trees.size(); ++x) { auto score = ScenicScore(x, y, trees); if(score > highest_scenic) { highest_scenic = score; std::cout << "New highest: " << score << " at " << x << "," << y << std::endl; } } } total_pt2 = highest_scenic; std::cout << "PT2 Total: " << total_pt2 << std::endl; return 0; }