Day 15: Replace sortedListReplacement with PriorityQueue
Use ImmutableHashSet instead of HashSet so visited points do not have to be copied Format code
This commit is contained in:
parent
3be5aca277
commit
ee2d1f4bda
40
Day15.cs
40
Day15.cs
|
|
@ -1,8 +1,8 @@
|
||||||
#define Day15
|
#define Day15
|
||||||
using System.Collections.Generic;
|
#if Day15
|
||||||
|
using System.Collections.Immutable;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using AoC2021;
|
using AoC2021;
|
||||||
#if Day15
|
|
||||||
|
|
||||||
var lines = File.ReadAllLines("day15/input");
|
var lines = File.ReadAllLines("day15/input");
|
||||||
var cave = new int[lines.Length, lines[0].Length];
|
var cave = new int[lines.Length, lines[0].Length];
|
||||||
|
|
@ -29,50 +29,29 @@ long Check(int[,] caveToCheck) {
|
||||||
var pos = new Point(0, 0);
|
var pos = new Point(0, 0);
|
||||||
var end = new Point(caveToCheck.GetLength(0) - 1, caveToCheck.GetLength(1) - 1);
|
var end = new Point(caveToCheck.GetLength(0) - 1, caveToCheck.GetLength(1) - 1);
|
||||||
var visitedLowest = new Dictionary<Point, long>() { { pos, 0 } };
|
var visitedLowest = new Dictionary<Point, long>() { { pos, 0 } };
|
||||||
long min = 0;
|
var minPaths = new PriorityQueue<PointWithVisited, long>();
|
||||||
var sortedListReplacement = new Dictionary<long, List<PointWithVisited>>() { { 0, new List<PointWithVisited>() { new PointWithVisited(pos, new HashSet<Point>()) } } };
|
minPaths.Enqueue(new PointWithVisited(pos, ImmutableHashSet.Create<Point>()), 0);
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
if (!sortedListReplacement.ContainsKey(min)) {
|
minPaths.TryDequeue(out PointWithVisited cur, out long min);
|
||||||
min++;
|
|
||||||
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
var minPoints = sortedListReplacement[min];
|
|
||||||
if (minPoints.Count <= 0) {
|
|
||||||
min++;
|
|
||||||
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
var cur = minPoints.First();
|
|
||||||
if (cur.point.Equals(end)) {
|
if (cur.point.Equals(end)) {
|
||||||
return min;
|
return min;
|
||||||
}
|
}
|
||||||
minPoints.Remove(cur);
|
|
||||||
|
|
||||||
var adjacent = GetAdjacent(cur.point, cur.visited, caveToCheck);
|
var adjacent = GetAdjacent(cur.point, cur.visited, caveToCheck);
|
||||||
|
var nextVisited = cur.visited.Add(cur.point);
|
||||||
foreach (var a in adjacent) {
|
foreach (var a in adjacent) {
|
||||||
var riskLevel = min + caveToCheck[a.row, a.col];
|
var riskLevel = min + caveToCheck[a.row, a.col];
|
||||||
if (visitedLowest.ContainsKey(a) && visitedLowest[a] <= riskLevel) {
|
if (visitedLowest.ContainsKey(a) && visitedLowest[a] <= riskLevel) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
visitedLowest[a] = riskLevel;
|
visitedLowest[a] = riskLevel;
|
||||||
AddToCheck(a, riskLevel, cur, sortedListReplacement);
|
minPaths.Enqueue(new PointWithVisited(a, nextVisited), riskLevel);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void AddToCheck(Point p, long sum, PointWithVisited previous, Dictionary<long, List<PointWithVisited>> sortedListReplacement) {
|
List<Point> GetAdjacent(Point cur, ImmutableHashSet<Point> visited, int[,] caveToCheck) {
|
||||||
var copy = previous.visited.ToHashSet();
|
|
||||||
copy.Add(previous.point);
|
|
||||||
if (!sortedListReplacement.ContainsKey(sum)) {
|
|
||||||
sortedListReplacement.Add(sum, new List<PointWithVisited>() {new PointWithVisited(p, copy)});
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
sortedListReplacement[sum].Add(new PointWithVisited(p, copy));
|
|
||||||
}
|
|
||||||
|
|
||||||
List<Point> GetAdjacent(Point cur, HashSet<Point> visited, int[,] caveToCheck) {
|
|
||||||
return new List<Point>() {
|
return new List<Point>() {
|
||||||
new Point(cur.row + 1, cur.col),
|
new Point(cur.row + 1, cur.col),
|
||||||
new Point(cur.row - 1, cur.col),
|
new Point(cur.row - 1, cur.col),
|
||||||
|
|
@ -83,6 +62,7 @@ List<Point> GetAdjacent(Point cur, HashSet<Point> visited, int[,] caveToCheck) {
|
||||||
.ToList();
|
.ToList();
|
||||||
}
|
}
|
||||||
|
|
||||||
record PointWithVisited(Point point, HashSet<Point> visited);
|
record PointWithVisited(Point point, ImmutableHashSet<Point> visited);
|
||||||
|
|
||||||
record Point(int row, int col);
|
record Point(int row, int col);
|
||||||
#endif
|
#endif
|
||||||
Loading…
Reference in New Issue