144 lines
3.0 KiB
C++
144 lines
3.0 KiB
C++
#include <fstream>
|
|
#include <iostream>
|
|
#include <set>
|
|
#include <string>
|
|
#include <vector>
|
|
|
|
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<std::vector<int>> 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<std::pair<int, int>> 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<int> 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";
|
|
else
|
|
std::cout << "\033[0m";
|
|
std::cout << trees[y][x];
|
|
}
|
|
std::cout << std::endl;
|
|
}
|
|
std::cout << "\033[0m";
|
|
|
|
std::cout << " Total: " << total << std::endl;
|
|
std::cout << "PT2 Total: " << total_pt2 << std::endl;
|
|
|
|
return 0;
|
|
}
|