parent
a263a89db3
commit
69a0ede3a3
3 changed files with 128 additions and 3 deletions
@ -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<Day12::Vertex, uint64> distances = dijkstra(g, start); |
||||
|
||||
uint64 result = distances[end]; |
||||
|
||||
return to_string(result); |
||||
} |
||||
|
||||
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