parent
a263a89db3
commit
69a0ede3a3
3 changed files with 128 additions and 3 deletions
@ -1,9 +1,119 @@ |
|||||||
#include "Day12.h" |
#include "Day12.h" |
||||||
|
|
||||||
Result Day12::Task1() { |
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<Day12::Vertex, uint64> distances = dijkstra(g, start); |
||||||
|
|
||||||
|
uint64 result = distances[end]; |
||||||
|
|
||||||
|
return to_string(result); |
||||||
} |
} |
||||||
|
|
||||||
Result Day12::Task2() { |
Result Day12::Task2() { |
||||||
return Day::Task2(); |
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<Vertex> 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<Day12::Vertex, uint64> 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::Vertex, uint64> Day12::dijkstra(Graph &graph, Vertex start) { |
||||||
|
set<Vertex> queue; |
||||||
|
map<Vertex, uint64> 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; |
||||||
} |
} |
Loading…
Reference in new issue