From ee2d1f4bda84b289a96cb108a25dceeb254902df Mon Sep 17 00:00:00 2001 From: Stefan Forstenlechner Date: Wed, 15 Dec 2021 23:16:18 +0100 Subject: [PATCH] Day 15: Replace sortedListReplacement with PriorityQueue Use ImmutableHashSet instead of HashSet so visited points do not have to be copied Format code --- Day15.cs | 56 ++++++++++++++++++-------------------------------------- 1 file changed, 18 insertions(+), 38 deletions(-) diff --git a/Day15.cs b/Day15.cs index edc679c..d49fa7e 100644 --- a/Day15.cs +++ b/Day15.cs @@ -1,23 +1,23 @@ #define Day15 -using System.Collections.Generic; +#if Day15 +using System.Collections.Immutable; using System.Diagnostics; using AoC2021; -#if Day15 var lines = File.ReadAllLines("day15/input"); var cave = new int[lines.Length, lines[0].Length]; -lines.ForEachIndex((l, row) => l.ForEachIndex((c, col)=> cave[row, col] = int.Parse(c.ToString()))); +lines.ForEachIndex((l, row) => l.ForEachIndex((c, col) => cave[row, col] = int.Parse(c.ToString()))); Console.WriteLine(Check(cave)); int rowLength = cave.GetLength(0); int colLength = cave.GetLength(1); -var largerCave = new int[lines.Length*5, lines[0].Length*5]; +var largerCave = new int[lines.Length * 5, lines[0].Length * 5]; for (int timeRow = 0; timeRow < 5; timeRow++) { for (int timesCol = 0; timesCol < 5; timesCol++) { for (int row = 0; row < rowLength; row++) { for (int col = 0; col < colLength; col++) { - largerCave[rowLength * timeRow + row, colLength*timesCol + col] = ((cave[row, col] + timeRow + timesCol - 1) % 9) + 1; + largerCave[rowLength * timeRow + row, colLength * timesCol + col] = ((cave[row, col] + timeRow + timesCol - 1) % 9) + 1; } } } @@ -29,60 +29,40 @@ long Check(int[,] caveToCheck) { var pos = new Point(0, 0); var end = new Point(caveToCheck.GetLength(0) - 1, caveToCheck.GetLength(1) - 1); var visitedLowest = new Dictionary() { { pos, 0 } }; - long min = 0; - var sortedListReplacement = new Dictionary>() { { 0, new List() { new PointWithVisited(pos, new HashSet()) } } }; + var minPaths = new PriorityQueue(); + minPaths.Enqueue(new PointWithVisited(pos, ImmutableHashSet.Create()), 0); while (true) { - if (!sortedListReplacement.ContainsKey(min)) { - min++; - - continue; - } - var minPoints = sortedListReplacement[min]; - if (minPoints.Count <= 0) { - min++; - - continue; - } - var cur = minPoints.First(); + minPaths.TryDequeue(out PointWithVisited cur, out long min); if (cur.point.Equals(end)) { return min; } - minPoints.Remove(cur); var adjacent = GetAdjacent(cur.point, cur.visited, caveToCheck); + var nextVisited = cur.visited.Add(cur.point); foreach (var a in adjacent) { var riskLevel = min + caveToCheck[a.row, a.col]; if (visitedLowest.ContainsKey(a) && visitedLowest[a] <= riskLevel) { continue; } visitedLowest[a] = riskLevel; - AddToCheck(a, riskLevel, cur, sortedListReplacement); + minPaths.Enqueue(new PointWithVisited(a, nextVisited), riskLevel); } } } -void AddToCheck(Point p, long sum, PointWithVisited previous, Dictionary> sortedListReplacement) { - var copy = previous.visited.ToHashSet(); - copy.Add(previous.point); - if (!sortedListReplacement.ContainsKey(sum)) { - sortedListReplacement.Add(sum, new List() {new PointWithVisited(p, copy)}); - return; - } - sortedListReplacement[sum].Add(new PointWithVisited(p, copy)); -} - -List GetAdjacent(Point cur, HashSet visited, int[,] caveToCheck) { +List GetAdjacent(Point cur, ImmutableHashSet visited, int[,] caveToCheck) { return new List() { - new Point(cur.row + 1, cur.col), - new Point(cur.row - 1, cur.col), - new Point(cur.row, cur.col + 1), - new Point(cur.row, cur.col - 1), - }.Where(p => p.row >= 0 && p.row < caveToCheck.GetLength(0) && p.col >= 0 && p.col < caveToCheck.GetLength(1)) + new Point(cur.row + 1, cur.col), + new Point(cur.row - 1, cur.col), + new Point(cur.row, cur.col + 1), + new Point(cur.row, cur.col - 1), + }.Where(p => p.row >= 0 && p.row < caveToCheck.GetLength(0) && p.col >= 0 && p.col < caveToCheck.GetLength(1)) .Where(p => !visited.Contains(p)) .ToList(); } -record PointWithVisited(Point point, HashSet visited); +record PointWithVisited(Point point, ImmutableHashSet visited); + record Point(int row, int col); #endif \ No newline at end of file