129 lines
3.1 KiB
C++
129 lines
3.1 KiB
C++
#include <iostream>
|
|
#include <array>
|
|
#include <cstdint>
|
|
#include <fstream>
|
|
#include <iterator>
|
|
#include <unordered_set>
|
|
|
|
using map_t = std::array<std::array<uint8_t, 55>, 54>;
|
|
|
|
struct Point
|
|
{
|
|
int16_t Row;
|
|
int16_t Col;
|
|
};
|
|
|
|
using sols_t = std::unordered_set<uint32_t>;
|
|
|
|
void load_map(map_t& map, const char* filepath)
|
|
{
|
|
std::fstream in(filepath);
|
|
std::istreambuf_iterator<char> iter(in);
|
|
// std::istream_iterator<char> end;
|
|
for (auto& row : map)
|
|
{
|
|
for (auto& cell : row)
|
|
{
|
|
cell = *(iter++);
|
|
}
|
|
}
|
|
}
|
|
|
|
void branch(const map_t& map, sols_t& terminals, char height, Point pos)
|
|
{
|
|
if (height == '9')
|
|
terminals.emplace((pos.Row << 16) + pos.Col);
|
|
else
|
|
{
|
|
if (pos.Row > 0 && map[pos.Row-1][pos.Col] == height+1)
|
|
{
|
|
branch(map, terminals, height+1, {pos.Row-1, pos.Col});
|
|
}
|
|
if (pos.Row < map.size()-1 && map[pos.Row+1][pos.Col] == height+1)
|
|
{
|
|
branch(map, terminals, height+1, {pos.Row+1, pos.Col});
|
|
}
|
|
if (pos.Col > 0 && map[pos.Row][pos.Col-1] == height+1)
|
|
{
|
|
branch(map, terminals, height+1, {pos.Row, pos.Col-1});
|
|
}
|
|
if (pos.Col < map[0].size()-2 && map[pos.Row][pos.Col+1] == height+1)
|
|
{
|
|
branch(map, terminals, height+1, {pos.Row, pos.Col+1});
|
|
}
|
|
}
|
|
}
|
|
|
|
int64_t branch2(const map_t& map, char height, Point pos)
|
|
{
|
|
if (height == '9')
|
|
return 1;
|
|
else
|
|
{
|
|
int64_t total = 0;
|
|
if (pos.Row > 0 && map[pos.Row-1][pos.Col] == height+1)
|
|
{
|
|
total += branch2(map, height+1, {pos.Row-1, pos.Col});
|
|
}
|
|
if (pos.Row < map.size()-1 && map[pos.Row+1][pos.Col] == height+1)
|
|
{
|
|
total += branch2(map, height+1, {pos.Row+1, pos.Col});
|
|
}
|
|
if (pos.Col > 0 && map[pos.Row][pos.Col-1] == height+1)
|
|
{
|
|
total += branch2(map, height+1, {pos.Row, pos.Col-1});
|
|
}
|
|
if (pos.Col < map[0].size()-2 && map[pos.Row][pos.Col+1] == height+1)
|
|
{
|
|
total += branch2(map, height+1, {pos.Row, pos.Col+1});
|
|
}
|
|
return total;
|
|
}
|
|
}
|
|
|
|
void main1(const map_t& map)
|
|
{
|
|
int total = 0;
|
|
// for (const auto& row : map)
|
|
// for (const auto& cell : row)
|
|
// std::cout << cell;
|
|
// std::cout << std::endl;
|
|
for (int16_t r = 0; r < map.size(); r++)
|
|
{
|
|
for (int16_t c = 0; c < map[r].size()-1; c++)
|
|
{
|
|
if (map[r][c] == '0')
|
|
{
|
|
sols_t terminals;
|
|
branch(map, terminals, '0', {r, c});
|
|
total += terminals.size();
|
|
}
|
|
}
|
|
}
|
|
std::cout << "Part1 " << total << std::endl;
|
|
}
|
|
|
|
void main2(const map_t& map)
|
|
{
|
|
int64_t total = 0;
|
|
for (int16_t r = 0; r < map.size(); r++)
|
|
{
|
|
for (int16_t c = 0; c < map[r].size()-1; c++)
|
|
{
|
|
if (map[r][c] == '0')
|
|
{
|
|
total += branch2(map, '0', {r, c});
|
|
}
|
|
}
|
|
}
|
|
std::cout << "Part2 " << total << std::endl;
|
|
}
|
|
|
|
int main()
|
|
{
|
|
map_t map;
|
|
load_map(map, "10.txt");
|
|
main1(map);
|
|
main2(map);
|
|
return 0;
|
|
} |