tidy up some warnings
This commit is contained in:
parent
fac10609e8
commit
9edb557cd9
|
@ -7,7 +7,7 @@ public sealed class Day14 : Day
|
||||||
{
|
{
|
||||||
private readonly string _template;
|
private readonly string _template;
|
||||||
private readonly Dictionary<string, string> _substitutionPairs;
|
private readonly Dictionary<string, string> _substitutionPairs;
|
||||||
|
|
||||||
public Day14() : base(14, "Extended Polymerization")
|
public Day14() : base(14, "Extended Polymerization")
|
||||||
{
|
{
|
||||||
_template = Input.First();
|
_template = Input.First();
|
||||||
|
@ -17,7 +17,7 @@ public sealed class Day14 : Day
|
||||||
private string DoStep(string input)
|
private string DoStep(string input)
|
||||||
{
|
{
|
||||||
var result = new StringBuilder();
|
var result = new StringBuilder();
|
||||||
|
|
||||||
for (var i = 0; i < input.Length - 1; i++)
|
for (var i = 0; i < input.Length - 1; i++)
|
||||||
{
|
{
|
||||||
var k = input.Substring(i, 2);
|
var k = input.Substring(i, 2);
|
||||||
|
@ -46,7 +46,7 @@ public sealed class Day14 : Day
|
||||||
moleculeCounts[k] = moleculeCounts.GetValueOrDefault(k) + 1;
|
moleculeCounts[k] = moleculeCounts.GetValueOrDefault(k) + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (var i in Enumerable.Range(0, steps))
|
foreach (var _ in Enumerable.Range(0, steps))
|
||||||
{
|
{
|
||||||
var updated = new Dictionary<string, long>();
|
var updated = new Dictionary<string, long>();
|
||||||
foreach (var (molecule, count) in moleculeCounts)
|
foreach (var (molecule, count) in moleculeCounts)
|
||||||
|
@ -58,7 +58,7 @@ public sealed class Day14 : Day
|
||||||
|
|
||||||
moleculeCounts = updated;
|
moleculeCounts = updated;
|
||||||
}
|
}
|
||||||
|
|
||||||
var elementCounts = new Dictionary<char, long>();
|
var elementCounts = new Dictionary<char, long>();
|
||||||
foreach (var (molecule, count) in moleculeCounts)
|
foreach (var (molecule, count) in moleculeCounts)
|
||||||
{
|
{
|
||||||
|
@ -81,7 +81,7 @@ public sealed class Day14 : Day
|
||||||
.OrderByDescending(g => g.Count())
|
.OrderByDescending(g => g.Count())
|
||||||
.Select(g => g.Count())
|
.Select(g => g.Count())
|
||||||
.ToList();
|
.ToList();
|
||||||
|
|
||||||
return most.First() - most.Last();
|
return most.First() - most.Last();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
public sealed class Day18 : Day
|
public sealed class Day18 : Day
|
||||||
{
|
{
|
||||||
private readonly List<string> _fishes;
|
private readonly List<string> _fishes;
|
||||||
|
|
||||||
public Day18() : base(18, "Snailfish")
|
public Day18() : base(18, "Snailfish")
|
||||||
{
|
{
|
||||||
_fishes = Input.ToList();
|
_fishes = Input.ToList();
|
||||||
|
@ -17,7 +17,7 @@ public sealed class Day18 : Day
|
||||||
static Tree<int>.Node ParseFish(Tree<int>.Node? parent, string input, ref int cursor)
|
static Tree<int>.Node ParseFish(Tree<int>.Node? parent, string input, ref int cursor)
|
||||||
{
|
{
|
||||||
if (input[cursor] != '[') return new(parent, input[cursor++] - '0');
|
if (input[cursor] != '[') return new(parent, input[cursor++] - '0');
|
||||||
|
|
||||||
var node = new Tree<int>.Node(parent, -1);
|
var node = new Tree<int>.Node(parent, -1);
|
||||||
cursor++;
|
cursor++;
|
||||||
node.Left = ParseFish(node, input, ref cursor);
|
node.Left = ParseFish(node, input, ref cursor);
|
||||||
|
@ -64,8 +64,7 @@ public sealed class Day18 : Day
|
||||||
{
|
{
|
||||||
if (reducer(tree, node)) return true;
|
if (reducer(tree, node)) return true;
|
||||||
if (node.Left != null && ReduceRecurse(node.Left, reducer)) return true;
|
if (node.Left != null && ReduceRecurse(node.Left, reducer)) return true;
|
||||||
if (node.Right != null && ReduceRecurse(node.Right, reducer)) return true;
|
return node.Right != null && ReduceRecurse(node.Right, reducer);
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Explode(Tree<int> t, Tree<int>.Node node)
|
bool Explode(Tree<int> t, Tree<int>.Node node)
|
||||||
|
@ -112,7 +111,7 @@ public sealed class Day18 : Day
|
||||||
public override object Part2()
|
public override object Part2()
|
||||||
{
|
{
|
||||||
var best = 0L;
|
var best = 0L;
|
||||||
for (var i = 0; i < _fishes.Count; i++)
|
for (var i = 0; i < _fishes.Count; i++)
|
||||||
best = _fishes
|
best = _fishes
|
||||||
.Where((_, j) => i != j)
|
.Where((_, j) => i != j)
|
||||||
.Select(t => Add(Parse(_fishes[i]), Parse(t)))
|
.Select(t => Add(Parse(_fishes[i]), Parse(t)))
|
||||||
|
|
|
@ -55,13 +55,13 @@ public sealed class Day19 : Day
|
||||||
|
|
||||||
private static Vector3 Translate(Vector3 p, Vector3 v) => (p.X + v.X, p.Y + v.Y, p.Z + v.Z);
|
private static Vector3 Translate(Vector3 p, Vector3 v) => (p.X + v.X, p.Y + v.Y, p.Z + v.Z);
|
||||||
private static Vector3 Difference(Vector3 p1, Vector3 p2) => (p1.X - p2.X, p1.Y - p2.Y, p1.Z - p2.Z);
|
private static Vector3 Difference(Vector3 p1, Vector3 p2) => (p1.X - p2.X, p1.Y - p2.Y, p1.Z - p2.Z);
|
||||||
|
|
||||||
private static int Manhattan(Vector3 a, Vector3 b)
|
private static int Manhattan(Vector3 a, Vector3 b)
|
||||||
{
|
{
|
||||||
var (dx, dy, dz) = Difference(a, b);
|
var (dx, dy, dz) = Difference(a, b);
|
||||||
return Math.Abs(dx) + Math.Abs(dy) + Math.Abs(dz);
|
return Math.Abs(dx) + Math.Abs(dy) + Math.Abs(dz);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static (HashSet<Vector3> alignedBeacons, Vector3 translation, Vector3 up, int rotation)? Align(
|
private static (HashSet<Vector3> alignedBeacons, Vector3 translation, Vector3 up, int rotation)? Align(
|
||||||
HashSet<Vector3> beacons1, IReadOnlyCollection<Vector3> beacons2)
|
HashSet<Vector3> beacons1, IReadOnlyCollection<Vector3> beacons2)
|
||||||
{
|
{
|
||||||
|
@ -120,7 +120,7 @@ public sealed class Day19 : Day
|
||||||
|
|
||||||
// Skip all scans and scanners that were merged
|
// Skip all scans and scanners that were merged
|
||||||
return (scans.Where((_, i) => !toRemove.Contains(i)).ToList(),
|
return (scans.Where((_, i) => !toRemove.Contains(i)).ToList(),
|
||||||
scanners.Where((el, i) => !toRemove.Contains(i)).ToList());
|
scanners.Where((_, i) => !toRemove.Contains(i)).ToList());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -130,7 +130,7 @@ public sealed class Day19 : Day
|
||||||
_scanners = scans.Select(_ => new HashSet<Vector3> { (0, 0, 0) }).ToList();
|
_scanners = scans.Select(_ => new HashSet<Vector3> { (0, 0, 0) }).ToList();
|
||||||
while (scans.Count > 1)
|
while (scans.Count > 1)
|
||||||
(scans, _scanners) = Reduce(scans, _scanners);
|
(scans, _scanners) = Reduce(scans, _scanners);
|
||||||
|
|
||||||
return scans[0].Count;
|
return scans[0].Count;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -70,9 +70,10 @@ public sealed class Day20 : Day
|
||||||
|
|
||||||
public int GetEnhanceInput(Point pt)
|
public int GetEnhanceInput(Point pt)
|
||||||
{
|
{
|
||||||
|
var (x, y) = pt;
|
||||||
var values =
|
var values =
|
||||||
Enumerable.Range(pt.Y - 1, 3)
|
Enumerable.Range(y - 1, 3)
|
||||||
.SelectMany(_ => Enumerable.Range(pt.X - 1, 3), (yi, xi) => this[new(xi, yi)] ? 1 : 0);
|
.SelectMany(_ => Enumerable.Range(x - 1, 3), (yi, xi) => this[new(xi, yi)] ? 1 : 0);
|
||||||
|
|
||||||
return values.Aggregate(0, (p, n) => (p << 1) | n);
|
return values.Aggregate(0, (p, n) => (p << 1) | n);
|
||||||
}
|
}
|
||||||
|
|
|
@ -50,7 +50,7 @@ public sealed class Day21 : Day
|
||||||
{
|
{
|
||||||
var pts = MoveSpaces(key, player1Pos);
|
var pts = MoveSpaces(key, player1Pos);
|
||||||
if (player1Points + pts < 21)
|
if (player1Points + pts < 21)
|
||||||
RollDiracDie(player1Points + pts, player2Points, pts, player2Pos, 2, (value * universes));
|
RollDiracDie(player1Points + pts, player2Points, pts, player2Pos, 2, value * universes);
|
||||||
else
|
else
|
||||||
_player1Victories += universes * value;
|
_player1Victories += universes * value;
|
||||||
}
|
}
|
||||||
|
@ -59,7 +59,7 @@ public sealed class Day21 : Day
|
||||||
{
|
{
|
||||||
var pts = MoveSpaces(key, player2Pos);
|
var pts = MoveSpaces(key, player2Pos);
|
||||||
if (player2Points + pts < 21)
|
if (player2Points + pts < 21)
|
||||||
RollDiracDie(player1Points, player2Points + pts, player1Pos, pts, 1, (value * universes));
|
RollDiracDie(player1Points, player2Points + pts, player1Pos, pts, 1, value * universes);
|
||||||
else
|
else
|
||||||
_player2Victories += universes * value;
|
_player2Victories += universes * value;
|
||||||
}
|
}
|
||||||
|
|
264
aoc2021/Utils.cs
264
aoc2021/Utils.cs
|
@ -2,20 +2,8 @@ namespace aoc2021;
|
||||||
|
|
||||||
public class DefaultDict<TKey, TValue> : Dictionary<TKey, TValue> where TKey : notnull
|
public class DefaultDict<TKey, TValue> : Dictionary<TKey, TValue> where TKey : notnull
|
||||||
{
|
{
|
||||||
public DefaultDict()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public DefaultDict(IDictionary<TKey, TValue> dict) : base(dict)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public TValue? DefaultValue;
|
public TValue? DefaultValue;
|
||||||
|
|
||||||
public DefaultDict(IEnumerable<KeyValuePair<TKey, TValue>> pairs) : base(pairs)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public new TValue? this[TKey key]
|
public new TValue? this[TKey key]
|
||||||
{
|
{
|
||||||
get => TryGetValue(key, out var t) ? t : DefaultValue;
|
get => TryGetValue(key, out var t) ? t : DefaultValue;
|
||||||
|
@ -90,178 +78,6 @@ public class Dijkstra<TCell, TMid> where TCell : notnull
|
||||||
public Func<TMid, int>? Distance;
|
public Func<TMid, int>? Distance;
|
||||||
public Func<TCell, TMid, TCell>? Cell;
|
public Func<TCell, TMid, TCell>? Cell;
|
||||||
|
|
||||||
public Dictionary<TCell, int> ComputeAll(TCell start, IEnumerable<TCell> all)
|
|
||||||
{
|
|
||||||
var dist = new Dictionary<TCell, int>();
|
|
||||||
foreach (var cell in all)
|
|
||||||
{
|
|
||||||
dist[cell] = int.MaxValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
dist[start] = 0;
|
|
||||||
var queue = new PriorityQueue<TCell, int>(dist.Select(pair => (pair.Key, pair.Value)));
|
|
||||||
while (queue.Count > 0)
|
|
||||||
{
|
|
||||||
var cell = queue.Dequeue();
|
|
||||||
var current = dist[cell];
|
|
||||||
foreach (var neighbor in Neighbors!(cell))
|
|
||||||
{
|
|
||||||
var other = Cell!(cell, neighbor);
|
|
||||||
var weight = Distance!(neighbor);
|
|
||||||
if (current + weight < dist[other])
|
|
||||||
{
|
|
||||||
dist[other] = current + weight;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return dist;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Dictionary<TCell, int> Compute(TCell start)
|
|
||||||
{
|
|
||||||
var dist = new DefaultDict<TCell, int> { DefaultValue = int.MaxValue, [start] = 0 };
|
|
||||||
var seen = new HashSet<TCell>();
|
|
||||||
var queue = new PriorityQueue<TCell, int>();
|
|
||||||
queue.Enqueue(start, 0);
|
|
||||||
while (queue.Count > 0)
|
|
||||||
{
|
|
||||||
var cell = queue.Dequeue();
|
|
||||||
if (seen.Contains(cell)) continue;
|
|
||||||
seen.Add(cell);
|
|
||||||
var current = dist[cell];
|
|
||||||
foreach (var neighbor in Neighbors!(cell))
|
|
||||||
{
|
|
||||||
var other = Cell!(cell, neighbor);
|
|
||||||
var weight = Distance!(neighbor);
|
|
||||||
if (!seen.Contains(other)) queue.Enqueue(other, current + weight);
|
|
||||||
if (current + weight < dist[other])
|
|
||||||
{
|
|
||||||
dist[other] = current + weight;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return dist;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int Count(TCell start, Func<TCell, bool> count)
|
|
||||||
{
|
|
||||||
var total = 0;
|
|
||||||
var seen = new HashSet<TCell>();
|
|
||||||
var queue = new Queue<TCell>();
|
|
||||||
queue.Enqueue(start);
|
|
||||||
while (queue.Count > 0)
|
|
||||||
{
|
|
||||||
var cell = queue.Dequeue();
|
|
||||||
if (seen.Contains(cell)) continue;
|
|
||||||
seen.Add(cell);
|
|
||||||
foreach (var neighbor in Neighbors!(cell))
|
|
||||||
{
|
|
||||||
var other = Cell!(cell, neighbor);
|
|
||||||
if (count(other))
|
|
||||||
{
|
|
||||||
total++;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!seen.Contains(other)) queue.Enqueue(other);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return total;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Dictionary<TCell, int> ComputeWhere(TCell start, Func<TCell, bool> valid)
|
|
||||||
{
|
|
||||||
var dist = new DefaultDict<TCell, int> { DefaultValue = int.MaxValue, [start] = 0 };
|
|
||||||
var seen = new HashSet<TCell>();
|
|
||||||
var queue = new PriorityQueue<TCell, int>();
|
|
||||||
queue.Enqueue(start, 0);
|
|
||||||
while (queue.Count > 0)
|
|
||||||
{
|
|
||||||
var cell = queue.Dequeue();
|
|
||||||
if (seen.Contains(cell)) continue;
|
|
||||||
seen.Add(cell);
|
|
||||||
var current = dist[cell];
|
|
||||||
foreach (var neighbor in Neighbors!(cell))
|
|
||||||
{
|
|
||||||
var other = Cell!(cell, neighbor);
|
|
||||||
if (!valid(other)) continue;
|
|
||||||
var weight = Distance!(neighbor);
|
|
||||||
if (!seen.Contains(other)) queue.Enqueue(other, current + weight);
|
|
||||||
if (current + weight < dist[other])
|
|
||||||
{
|
|
||||||
dist[other] = current + weight;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return dist;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Dictionary<TCell, (int Dist, TCell From)> ComputeFrom(TCell start, Func<TCell, bool>? valid = null)
|
|
||||||
{
|
|
||||||
valid ??= _ => true;
|
|
||||||
var dist = new DefaultDict<TCell, (int Dist, TCell From)>
|
|
||||||
{ DefaultValue = (int.MaxValue, default)!, [start] = (0, default)! };
|
|
||||||
var seen = new HashSet<TCell>();
|
|
||||||
var queue = new PriorityQueue<TCell, int>();
|
|
||||||
queue.Enqueue(start, 0);
|
|
||||||
while (queue.Count > 0)
|
|
||||||
{
|
|
||||||
var cell = queue.Dequeue();
|
|
||||||
if (seen.Contains(cell)) continue;
|
|
||||||
seen.Add(cell);
|
|
||||||
var current = dist[cell].Dist;
|
|
||||||
foreach (var neighbor in Neighbors!(cell))
|
|
||||||
{
|
|
||||||
var other = Cell!(cell, neighbor);
|
|
||||||
if (!valid(other)) continue;
|
|
||||||
var weight = Distance!(neighbor);
|
|
||||||
if (!seen.Contains(other)) queue.Enqueue(other, current + weight);
|
|
||||||
if (current + weight < dist[other].Dist)
|
|
||||||
{
|
|
||||||
dist[other] = (current + weight, cell);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return dist;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Dictionary<TCell, (int Dist, TCell From)> ComputePath(TCell start, TCell target,
|
|
||||||
Func<TCell, bool>? valid = null)
|
|
||||||
{
|
|
||||||
valid ??= _ => true;
|
|
||||||
var dist = new DefaultDict<TCell, (int Dist, TCell From)>
|
|
||||||
{ DefaultValue = (int.MaxValue, default)!, [start] = (0, default)! };
|
|
||||||
var seen = new HashSet<TCell>();
|
|
||||||
var queue = new PriorityQueue<TCell, int>();
|
|
||||||
queue.Enqueue(start, 0);
|
|
||||||
while (queue.Count > 0)
|
|
||||||
{
|
|
||||||
var cell = queue.Dequeue();
|
|
||||||
if (seen.Contains(cell)) continue;
|
|
||||||
seen.Add(cell);
|
|
||||||
if (Equals(cell, target)) return dist;
|
|
||||||
var current = dist[cell].Dist;
|
|
||||||
foreach (var neighbor in Neighbors!(cell))
|
|
||||||
{
|
|
||||||
var other = Cell!(cell, neighbor);
|
|
||||||
if (!valid(other)) continue;
|
|
||||||
var weight = Distance!(neighbor);
|
|
||||||
if (!seen.Contains(other)) queue.Enqueue(other, current + weight);
|
|
||||||
if (current + weight < dist[other].Dist)
|
|
||||||
{
|
|
||||||
dist[other] = (current + weight, cell);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return dist;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int ComputeFind(TCell start, TCell target, Func<TCell, bool>? valid = null)
|
public int ComputeFind(TCell start, TCell target, Func<TCell, bool>? valid = null)
|
||||||
{
|
{
|
||||||
valid ??= _ => true;
|
valid ??= _ => true;
|
||||||
|
@ -291,84 +107,4 @@ public class Dijkstra<TCell, TMid> where TCell : notnull
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
public interface IDijkstra<TCell, TMid>
|
|
||||||
{
|
|
||||||
IEnumerable<TMid> GetNeighbors(TCell cell);
|
|
||||||
|
|
||||||
int GetWeight(TMid mid);
|
|
||||||
|
|
||||||
TCell GetNeighbor(TCell from, TMid mid);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class DijkstraExtensions
|
|
||||||
{
|
|
||||||
private static Dijkstra<TCell, TMid> Build<TCell, TMid>(this IDijkstra<TCell, TMid> dijkstra) where TCell : notnull
|
|
||||||
{
|
|
||||||
return new()
|
|
||||||
{
|
|
||||||
Neighbors = dijkstra.GetNeighbors,
|
|
||||||
Distance = dijkstra.GetWeight,
|
|
||||||
Cell = dijkstra.GetNeighbor
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Dijkstra<TCell, TMid> ToDijkstra<TCell, TMid>(this IDijkstra<TCell, TMid> dijkstra)
|
|
||||||
where TCell : notnull
|
|
||||||
{
|
|
||||||
return dijkstra.Build();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Dictionary<TCell, int> DijkstraAll<TCell, TMid>(this IDijkstra<TCell, TMid> dijkstra, TCell start,
|
|
||||||
IEnumerable<TCell> all) where TCell : notnull
|
|
||||||
{
|
|
||||||
return dijkstra.Build().ComputeAll(start, all);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Dictionary<TCell, int> Dijkstra<TCell, TMid>(this IDijkstra<TCell, TMid> dijkstra, TCell start)
|
|
||||||
where TCell : notnull
|
|
||||||
{
|
|
||||||
return dijkstra.Build().Compute(start);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Dictionary<TCell, int> DijkstraWhere<TCell, TMid>(this IDijkstra<TCell, TMid> dijkstra, TCell start,
|
|
||||||
Func<TCell, bool> valid) where TCell : notnull
|
|
||||||
{
|
|
||||||
return dijkstra.Build().ComputeWhere(start, valid);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Dictionary<TCell, (int Dist, TCell From)> DijkstraFrom<TCell, TMid>(
|
|
||||||
this IDijkstra<TCell, TMid> dijkstra, TCell start, Func<TCell, bool>? valid = null) where TCell : notnull
|
|
||||||
{
|
|
||||||
return dijkstra.Build().ComputeFrom(start, valid);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static int DijkstraFind<TCell, TMid>(this IDijkstra<TCell, TMid> dijkstra, TCell start, TCell target,
|
|
||||||
Func<TCell, bool>? valid = null) where TCell : notnull
|
|
||||||
{
|
|
||||||
return dijkstra.Build().ComputeFind(start, target, valid);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Dictionary<TCell, (int Dist, TCell From)> DijkstraPath<TCell, TMid>(
|
|
||||||
this IDijkstra<TCell, TMid> dijkstra, TCell start, TCell target, Func<TCell, bool>? valid = null)
|
|
||||||
where TCell : notnull
|
|
||||||
{
|
|
||||||
return dijkstra.Build().ComputePath(start, target, valid);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static IReadOnlyCollection<TCell> GetPathTo<TCell>(this Dictionary<TCell, (int Dist, TCell From)> dist,
|
|
||||||
TCell target) where TCell : notnull
|
|
||||||
{
|
|
||||||
var list = new LinkedList<TCell>();
|
|
||||||
list.AddFirst(target);
|
|
||||||
while (true)
|
|
||||||
{
|
|
||||||
if (!dist.TryGetValue(target, out var pair)) return Array.Empty<TCell>();
|
|
||||||
if (pair.Dist == 0) break;
|
|
||||||
list.AddFirst(target = pair.From);
|
|
||||||
}
|
|
||||||
|
|
||||||
return list;
|
|
||||||
}
|
|
||||||
}
|
}
|
Loading…
Reference in New Issue