generated from mazharenko/aoc-agent-template-multipleyears
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
2100777
commit 30d27c3
Showing
13 changed files
with
214 additions
and
257 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
using System.Collections; | ||
|
||
namespace aoc.Common.Search; | ||
|
||
public static class Bfs | ||
{ | ||
public static BfsBuilder<T, T> StartWith<T>(T start) | ||
{ | ||
return new BfsBuilder<T, T>(start, x => x); | ||
} | ||
} | ||
|
||
public class Bfs<T, TVisitedKey>(T start, IAdjacency<T> adjacency, Func<T, TVisitedKey>? visitedKey) : IEnumerable<Path<T>> | ||
{ | ||
public IEnumerator<Path<T>> GetEnumerator() | ||
{ | ||
var visited = new HashSet<TVisitedKey?>(); | ||
if (visitedKey is not null) | ||
visited.Add(visitedKey(start)); | ||
var queue = new PriorityQueue<Path<T>, int>(); | ||
queue.Enqueue(new Path<T>(L.Singleton(new PathItem<T>(start, 0))), int.MaxValue); | ||
while (true) | ||
{ | ||
if (queue.Count == 0) yield break; | ||
var currentPath = queue.Dequeue(); | ||
|
||
yield return currentPath; | ||
|
||
var current = currentPath.PathList.Head; | ||
var adjacent = adjacency.GetAdjacent(current.Item); | ||
foreach (var (adjacentValue, weight) in adjacent) | ||
{ | ||
if (visitedKey is null || visited.Add(visitedKey(adjacentValue))) | ||
queue.Enqueue(new Path<T>(currentPath.PathList.Prepend(new PathItem<T>(adjacentValue, current.Len + weight))), current.Len + weight); | ||
} | ||
} | ||
} | ||
|
||
// todo: Enumerable<T>? Enumerable<PathItem<T>>? | ||
|
||
IEnumerator IEnumerable.GetEnumerator() | ||
{ | ||
return GetEnumerator(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
namespace aoc.Common.Search; | ||
|
||
public class BfsBuilder<T, TVisitedKey>(T start, Func<T, TVisitedKey>? visitedKeyFunction) | ||
{ | ||
public BfsBuilder<T, TNewKey> WithVisitedKey<TNewKey>(Func<T, TNewKey> visited) | ||
{ | ||
return new BfsBuilder<T, TNewKey>(start, visited); | ||
} | ||
|
||
public BfsBuilder<T, object> WithoutTrackingVisited() | ||
{ | ||
return new BfsBuilder<T, object>(start, null); | ||
} | ||
|
||
public Bfs<T, TVisitedKey> WithAdjacency(Func<T, (T newState, int weight)[]> adjacency) | ||
=> WithAdjacency(new AdhocAdjacency<T>(adjacency)); | ||
|
||
public Bfs<T, TVisitedKey> WithAdjacency(Func<T, IEnumerable<T>> adjacency) | ||
=> WithAdjacency(new AdhocAdjacency<T>(state => adjacency(state).Select(newState => (newState, 1)))); | ||
|
||
public Bfs<T, TVisitedKey> WithAdjacency(IAdjacency<T> adjacency) | ||
=> new(start, adjacency, visitedKeyFunction); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
namespace aoc.Common.Search; | ||
|
||
public readonly record struct PathItem<T>(T Item, int Len); | ||
|
||
public readonly record struct Path<T>(L<PathItem<T>> PathList) | ||
{ | ||
public T HeadItem { get; } = PathList.Head.Item; | ||
public int Len => PathList.Head.Len; | ||
} | ||
|
||
public abstract record Result<T>; | ||
|
||
public static class ResultExtensions | ||
{ | ||
public static TRes Match<T, TRes>(this Result<T> result, Func<Path<T>, TRes> onFound, Func<TRes> onNotFound) | ||
{ | ||
return result switch | ||
{ | ||
Found<T> found => onFound(found.Path), | ||
NotFound<T> => onNotFound(), | ||
_ => throw new ArgumentOutOfRangeException(nameof(result)) | ||
}; | ||
} | ||
|
||
public static void Match<T>(this Result<T> result, Action<Path<T>> onFound, Action onNotFound) | ||
{ | ||
switch (result) | ||
{ | ||
case Found<T> found: | ||
onFound(found.Path); | ||
break; | ||
case NotFound<T>: | ||
onNotFound(); | ||
break; | ||
default: | ||
throw new ArgumentOutOfRangeException(nameof(result)); | ||
} | ||
} | ||
|
||
public static Path<T> AsFound<T>(this Result<T> result) => | ||
Match(result, p => p, () => throw new InvalidOperationException("The result was not 'Found'")); | ||
} | ||
|
||
public record Found<T>(Path<T> Path) : Result<T>; | ||
|
||
public record NotFound<T> : Result<T>; | ||
|
||
public interface IAdjacency<T> | ||
{ | ||
IEnumerable<(T newState, int weight)> GetAdjacent(T state); | ||
} | ||
|
||
public class AdhocAdjacency<T>(Func<T, IEnumerable<(T newState, int weight)>> function) : IAdjacency<T> | ||
{ | ||
public IEnumerable<(T newState, int weight)> GetAdjacent(T pos) => function(pos); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
namespace aoc.Common.Search; | ||
|
||
|
||
public delegate bool Target<in T>(T state); // ITarget? | ||
|
||
public static class Targets | ||
{ | ||
public static Target<T> Value<T>(T value) | ||
=> state => Equals(value, state); | ||
} | ||
|
||
public static class PathEnumerableExtensions | ||
{ | ||
public static Path<T> FindTarget<T>(this IEnumerable<Path<T>> paths, Target<T> target) | ||
{ | ||
return paths.First(path => target(path.HeadItem)); | ||
} | ||
|
||
public static Result<T> TryFindTarget<T>(this IEnumerable<Path<T>> paths, Target<T> target) | ||
{ | ||
foreach (var path in paths) | ||
{ | ||
if (target(path.HeadItem)) | ||
return new Found<T>(path); | ||
} | ||
|
||
return new NotFound<T>(); | ||
} | ||
|
||
public static IEnumerable<T> Items<T>(this IEnumerable<Path<T>> paths) | ||
=> paths.Select(path => path.HeadItem); | ||
} |
Oops, something went wrong.