diff --git a/src/days/12/Day12.cpp b/src/days/12/Day12.cpp index fd9f16d..387efd3 100644 --- a/src/days/12/Day12.cpp +++ b/src/days/12/Day12.cpp @@ -1,9 +1,119 @@ #include "Day12.h" Result Day12::Task1() { - return Day::Task1(); + Graph g = parseGraph(false); + + Vertex start = *std::find_if(g.V.begin(), g.V.end(), [this](Vertex v){ + return input[v.second][v.first] == 'S'; + }); + Vertex end = *std::find_if(g.V.begin(), g.V.end(), [this](Vertex v){ + return input[v.second][v.first] == 'E'; + }); + + map distances = dijkstra(g, start); + + uint64 result = distances[end]; + + return to_string(result); } Result Day12::Task2() { - return Day::Task2(); -} \ No newline at end of file + Graph g = parseGraph(true); + + Vertex start = *std::find_if(g.V.begin(), g.V.end(), [this](Vertex v){ + return input[v.second][v.first] == 'E'; + }); + + set endVertices; + std::copy_if(g.V.begin(), g.V.end(), std::inserter(endVertices, endVertices.begin()), [this](Vertex v){ + char c = input[v.second][v.first]; + return c == 'a' || c == 'S'; + }); + + map distances = dijkstra(g, start); + + + uint64 result = distances[*std::min_element(endVertices.begin(), endVertices.end(), [&distances](Vertex v1, Vertex v2){ + return distances[v1] < distances[v2]; + })]; + + return to_string(result); +} + +map Day12::dijkstra(Graph &graph, Vertex start) { + set queue; + map dist; + for (Vertex v : graph.V){ + dist[v] = UINT64_MAX - 1; + queue.insert(v); + } + dist[start] = 0; + + while (!queue.empty()){ + Vertex u; + uint64 uMin = UINT64_MAX; + for (const Vertex &v : queue){ + if (dist[v] < uMin){ + uMin = dist[v]; + u = v; + } + } + + queue.erase(u); + + for (const Vertex &v : graph.V){ + if (!graph.E.contains({u, v}) || !queue.contains(v)) + continue; + + size_t newDist = dist[u] + 1; + if (newDist < dist[v]) + dist[v] = newDist; + } + } + return dist; +} + +Day12::Graph Day12::parseGraph(bool reverse) { + Graph g; + + size_t dimX = input[0].size(); + size_t dimY = input.size(); + + for (size_t x = 0; x < dimX; x++) + for (size_t y = 0; y < dimY; y++) + g.V.emplace(x, y); + + auto invertChar = [](char var){ + return var + int((double(('a' + 'z')) / 2 - var) * 2); + }; + + auto readChar = [reverse, invertChar](char var){ + if (var == 'E') + var = 'z'; + if (var == 'S') + var = 'a'; + if (reverse) + var = invertChar(var); + return var; + }; + + auto checkEdges = [&g, readChar, this](Vertex v1, Vertex v2){ + char c1 = readChar(input[v1.second][v1.first]); + char c2 = readChar(input[v2.second][v2.first]); + if (c2 <= c1 + 1) + g.E.insert({v1, v2}); + if (c1 <= c2 + 1) + g.E.insert({v2, v1}); + }; + + for (Vertex v : g.V){ + size_t x = v.first; + size_t y = v.second; + if (x < dimX - 1) + checkEdges({x, y}, {x + 1, y}); + if (y < dimY - 1) + checkEdges({x, y}, {x, y + 1}); + } + + return g; +} diff --git a/src/days/12/Day12.h b/src/days/12/Day12.h index 1d4054d..c4811e5 100644 --- a/src/days/12/Day12.h +++ b/src/days/12/Day12.h @@ -3,8 +3,21 @@ #include "../../Day.h" class Day12 : public Day { + + typedef pair Vertex; + typedef pair Edge; + + struct Graph { + set V; + set E; + }; + + map dijkstra(Graph&,Vertex); + protected: Result Task1() override; Result Task2() override; + + Graph parseGraph(bool); }; \ No newline at end of file diff --git a/src/util.h b/src/util.h index f3d2df7..c369cce 100644 --- a/src/util.h +++ b/src/util.h @@ -8,6 +8,7 @@ #include #include #include +#include typedef uint64_t uint64; @@ -15,6 +16,7 @@ using std::stoi, std::to_string; using std::cout, std::endl; using std::string, std::vector, std::set, std::pair, std::map; using std::list; +using std::priority_queue; inline vector findAll(const string& data, const string& toSearch){ vector indices;