From bff6576a6c246e090adc4d0cd5723fb98fadf5cd Mon Sep 17 00:00:00 2001 From: Ikatono Date: Tue, 10 Dec 2024 17:44:56 -0600 Subject: [PATCH] added 10 with head caching --- 10_cacheheads.cpp | 290 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 290 insertions(+) create mode 100644 10_cacheheads.cpp diff --git a/10_cacheheads.cpp b/10_cacheheads.cpp new file mode 100644 index 0000000..4d99b45 --- /dev/null +++ b/10_cacheheads.cpp @@ -0,0 +1,290 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +#define WIDTH 54 +#define HEIGHT 54 + +using map_t = std::array, HEIGHT>; + +struct Point +{ + int_fast8_t Row; + int_fast8_t Col; +}; +std::ostream& operator<<(std::ostream& os, const Point& p) +{ + os << "{" << (int)p.Row << ", " << (int)p.Col << "}"; + return os; +} + +using heads_t = std::vector; + +struct sols_t +{ + std::bitset bits; + void emplace(Point point) + { + bits.set(point.Row * WIDTH + point.Col); + } + int size() const + { + return bits.count(); + } + void clear() + { + bits.reset(); + } +}; + +void load_map(map_t& map, heads_t& heads, const char* filepath) +{ + std::fstream in(filepath); + std::istreambuf_iterator iter(in); + for (int_fast8_t row = 0; row < map.size(); row++) + { + for (int_fast8_t col = 0; col < map[0].size(); col++) + { + map[row][col] = *(iter++) - '0'; + if (map[row][col] == 0) + { + Point p(row, col); + heads.push_back(p); + // heads.push_back({row, col}); + } + } + iter++; + } +} + +void quick_branch(const map_t& map, sols_t& terminals, Point init) +{ + std::array path; + int_fast8_t height = 0; + path[0] = 0; + Point pos = init; + while (height >= 0) + { + // const auto& pos = path[height].pos; + switch (path[height]++) + { + case 0: + if (pos.Row > 0 && map[pos.Row-1][pos.Col] == height+1) + { + if (height == 8) + terminals.emplace({static_cast(pos.Row-1), pos.Col}); + else + { + path[++height] = 0; + pos.Row--; + } + } + break; + case 1: + if (pos.Col < WIDTH-1 && map[pos.Row][pos.Col+1] == height+1) + { + if (height == 8) + terminals.emplace({pos.Row, static_cast(pos.Col+1)}); + else + { + path[++height] = 0; + pos.Col++; + } + } + break; + case 2: + if (pos.Row < HEIGHT-1 && map[pos.Row+1][pos.Col] == height+1) + { + if (height == 8) + terminals.emplace({static_cast(pos.Row+1), pos.Col}); + else + { + path[++height] = 0; + pos.Row++; + } + } + break; + case 3: + if (pos.Col > 0 && map[pos.Row][pos.Col-1] == height+1) + { + if (height == 8) + terminals.emplace({pos.Row, static_cast(pos.Col-1)}); + else + { + path[++height] = 0; + pos.Col--; + } + } + break; + default: + if (height > 0) + //remember that the previous path was already incremented + switch (path[height-1]) + { + case 1: + pos.Row++; + break; + case 2: + pos.Col--; + break; + case 3: + pos.Row--; + break; + case 4: + pos.Col++; + break; + } + height--; + break; + } + } +} + +int quick_branch2(const map_t& map, Point init) +{ + std::array path; + int_fast8_t height = 0; + path[0] = 0; + int total = 0; + Point pos = init; + while (height >= 0) + { + switch (path[height]++) + { + case 0: + if (pos.Row > 0 && map[pos.Row-1][pos.Col] == height+1) + { + if (height == 8) + total++; + else + { + path[++height] = 0; + pos.Row--; + } + } + break; + case 1: + if (pos.Col < WIDTH-1 && map[pos.Row][pos.Col+1] == height+1) + { + if (height == 8) + total++; + else + { + path[++height] = 0; + pos.Col++; + } + } + break; + case 2: + if (pos.Row < HEIGHT-1 && map[pos.Row+1][pos.Col] == height+1) + { + if (height == 8) + total++; + else + { + path[++height] = 0; + pos.Row++; + } + } + break; + case 3: + if (pos.Col > 0 && map[pos.Row][pos.Col-1] == height+1) + { + if (height == 8) + total++; + else + { + path[++height] = 0; + pos.Col--; + } + } + break; + default: + if (height > 0) + //remember that the previous path was already incremented + switch (path[height-1]) + { + case 1: + pos.Row++; + break; + case 2: + pos.Col--; + break; + case 3: + pos.Row--; + break; + case 4: + pos.Col++; + break; + } + height--; + break; + } + } + return total; +} + +void main1(const map_t& map, const heads_t& heads) +{ + int total = 0; + sols_t terminals; + terminals.clear(); + // for (int8_t r = 0; r < map.size(); r++) + // { + // for (int8_t c = 0; c < map[r].size(); c++) + // { + // if (map[r][c] == 0) + // { + // quick_branch(map, terminals, {r, c}); + // total += terminals.size(); + // terminals.clear(); + // } + // } + // } + for (const Point& pos : heads) + { + quick_branch(map, terminals, pos); + total += terminals.size(); + terminals.clear(); + } + std::cout << "Part1 " << total << std::endl; +} + +void main2(const map_t& map, const heads_t& heads) +{ + int32_t total = 0; + // for (int8_t r = 0; r < map.size(); r++) + // { + // for (int8_t c = 0; c < map[r].size(); c++) + // { + // if (map[r][c] == 0) + // { + // total += quick_branch2(map, {r, c}); + // } + // } + // } + for (const Point& pos : heads) + { + total += quick_branch2(map, pos); + } + std::cout << "Part2 " << total << std::endl; +} + +int main() +{ + map_t map; + heads_t heads; + load_map(map, heads, "10.txt"); + // std::print("{}", heads); + // for (const auto& head : heads) + // std::cout << head << " "; + // std::cout << std::endl; + main1(map, heads); + main2(map, heads); + return 0; +} \ No newline at end of file