├── .github
├── docfx.json
└── workflows
│ └── dotnetcore.yml
├── .gitignore
├── .vscode
├── settings.json
└── tasks.json
├── LICENSE
├── NuGet.config
├── PULL_REQUEST_TEMPLATE.md
├── README.md
├── _config.yml
├── docs
├── api
│ ├── Advanced.Algorithms.Binary.BaseConversion.html
│ ├── Advanced.Algorithms.Binary.BitHacks.html
│ ├── Advanced.Algorithms.Binary.DivisionModulus.html
│ ├── Advanced.Algorithms.Binary.Gcd.html
│ ├── Advanced.Algorithms.Binary.IntToBinary.html
│ ├── Advanced.Algorithms.Binary.IsMultipleOfNine.html
│ ├── Advanced.Algorithms.Binary.IsMultipleOfThree.html
│ ├── Advanced.Algorithms.Binary.Logarithm.html
│ ├── Advanced.Algorithms.Binary.NextPowOfTwo.html
│ ├── Advanced.Algorithms.Binary.ToggleCase.html
│ ├── Advanced.Algorithms.Binary.html
│ ├── Advanced.Algorithms.Combinatorics.Combination.html
│ ├── Advanced.Algorithms.Combinatorics.Permutation.html
│ ├── Advanced.Algorithms.Combinatorics.Subset.html
│ ├── Advanced.Algorithms.Combinatorics.html
│ ├── Advanced.Algorithms.Compression.HuffmanCoding-1.html
│ ├── Advanced.Algorithms.Compression.html
│ ├── Advanced.Algorithms.DataStructures.AVLTree-1.html
│ ├── Advanced.Algorithms.DataStructures.ArrayList-1.html
│ ├── Advanced.Algorithms.DataStructures.ArrayListEnumerator-1.html
│ ├── Advanced.Algorithms.DataStructures.BHeap-1.html
│ ├── Advanced.Algorithms.DataStructures.BMaxHeap-1.html
│ ├── Advanced.Algorithms.DataStructures.BMinHeap-1.html
│ ├── Advanced.Algorithms.DataStructures.BST-1.html
│ ├── Advanced.Algorithms.DataStructures.BSTBase-1.html
│ ├── Advanced.Algorithms.DataStructures.BSTExtensions.html
│ ├── Advanced.Algorithms.DataStructures.BTree-1.html
│ ├── Advanced.Algorithms.DataStructures.BinaryTree-1.html
│ ├── Advanced.Algorithms.DataStructures.BinaryTreeNode-1.html
│ ├── Advanced.Algorithms.DataStructures.BinomialHeap-1.html
│ ├── Advanced.Algorithms.DataStructures.BinomialHeapNode-1.html
│ ├── Advanced.Algorithms.DataStructures.BinomialMaxHeap-1.html
│ ├── Advanced.Algorithms.DataStructures.BinomialMinHeap-1.html
│ ├── Advanced.Algorithms.DataStructures.BloomFilter-1.html
│ ├── Advanced.Algorithms.DataStructures.BpTree-1.html
│ ├── Advanced.Algorithms.DataStructures.BpTreeEnumerator-1.html
│ ├── Advanced.Algorithms.DataStructures.CircularLinkedList-1.html
│ ├── Advanced.Algorithms.DataStructures.CircularLinkedListEnumerator-1.html
│ ├── Advanced.Algorithms.DataStructures.CircularLinkedListNode-1.html
│ ├── Advanced.Algorithms.DataStructures.DInterval-1.html
│ ├── Advanced.Algorithms.DataStructures.DIntervalTree-1.html
│ ├── Advanced.Algorithms.DataStructures.DRangeTree-1.html
│ ├── Advanced.Algorithms.DataStructures.D_aryMaxHeap-1.html
│ ├── Advanced.Algorithms.DataStructures.D_aryMinHeap-1.html
│ ├── Advanced.Algorithms.DataStructures.DaryHeap-1.html
│ ├── Advanced.Algorithms.DataStructures.DaryMaxHeap-1.html
│ ├── Advanced.Algorithms.DataStructures.DaryMinHeap-1.html
│ ├── Advanced.Algorithms.DataStructures.Dictionaries.Dictionary-2.html
│ ├── Advanced.Algorithms.DataStructures.Dictionaries.DictionaryType.html
│ ├── Advanced.Algorithms.DataStructures.Dictionaries.SortedDictionary-2.html
│ ├── Advanced.Algorithms.DataStructures.Dictionaries.html
│ ├── Advanced.Algorithms.DataStructures.Dictionary-2.html
│ ├── Advanced.Algorithms.DataStructures.DictionaryNode-2.html
│ ├── Advanced.Algorithms.DataStructures.DictionaryType.html
│ ├── Advanced.Algorithms.DataStructures.DisJointSet-1.html
│ ├── Advanced.Algorithms.DataStructures.DoublyLinkedList-1.html
│ ├── Advanced.Algorithms.DataStructures.DoublyLinkedListEnumerator-1.html
│ ├── Advanced.Algorithms.DataStructures.DoublyLinkedListNode-1.html
│ ├── Advanced.Algorithms.DataStructures.ExpressionTree-1.html
│ ├── Advanced.Algorithms.DataStructures.FenwickTree-1.html
│ ├── Advanced.Algorithms.DataStructures.FibonacciHeap-1.html
│ ├── Advanced.Algorithms.DataStructures.FibornacciHeap-1.html
│ ├── Advanced.Algorithms.DataStructures.FibornacciHeapNode-1.html
│ ├── Advanced.Algorithms.DataStructures.FibornacciMaxHeap-1.html
│ ├── Advanced.Algorithms.DataStructures.FibornacciMinHeap-1.html
│ ├── Advanced.Algorithms.DataStructures.Foundation.ArrayList-1.html
│ ├── Advanced.Algorithms.DataStructures.Foundation.Dictionary-2.html
│ ├── Advanced.Algorithms.DataStructures.Foundation.DictionaryType.html
│ ├── Advanced.Algorithms.DataStructures.Foundation.HashSet-1.html
│ ├── Advanced.Algorithms.DataStructures.Foundation.HashSetType.html
│ ├── Advanced.Algorithms.DataStructures.Foundation.OrderedDictionary-2.html
│ ├── Advanced.Algorithms.DataStructures.Foundation.OrderedHashSet-1.html
│ ├── Advanced.Algorithms.DataStructures.Foundation.Queue-1.html
│ ├── Advanced.Algorithms.DataStructures.Foundation.QueueType.html
│ ├── Advanced.Algorithms.DataStructures.Foundation.SortedDictionary-2.html
│ ├── Advanced.Algorithms.DataStructures.Foundation.SortedHashSet-1.html
│ ├── Advanced.Algorithms.DataStructures.Foundation.Stack-1.html
│ ├── Advanced.Algorithms.DataStructures.Foundation.StackType.html
│ ├── Advanced.Algorithms.DataStructures.Foundation.html
│ ├── Advanced.Algorithms.DataStructures.Graph.AdjacencyList.DiGraph-1.html
│ ├── Advanced.Algorithms.DataStructures.Graph.AdjacencyList.DiGraphVertex-1.html
│ ├── Advanced.Algorithms.DataStructures.Graph.AdjacencyList.Graph-1.html
│ ├── Advanced.Algorithms.DataStructures.Graph.AdjacencyList.GraphVertex-1.html
│ ├── Advanced.Algorithms.DataStructures.Graph.AdjacencyList.WeightedDiGraph-2.html
│ ├── Advanced.Algorithms.DataStructures.Graph.AdjacencyList.WeightedDiGraphVertex-2.html
│ ├── Advanced.Algorithms.DataStructures.Graph.AdjacencyList.WeightedGraph-2.html
│ ├── Advanced.Algorithms.DataStructures.Graph.AdjacencyList.WeightedGraphVertex-2.html
│ ├── Advanced.Algorithms.DataStructures.Graph.AdjacencyList.html
│ ├── Advanced.Algorithms.DataStructures.Graph.AdjacencyMatrix.DiGraph-1.html
│ ├── Advanced.Algorithms.DataStructures.Graph.AdjacencyMatrix.Graph-1.html
│ ├── Advanced.Algorithms.DataStructures.Graph.AdjacencyMatrix.WeightedDiGraph-2.html
│ ├── Advanced.Algorithms.DataStructures.Graph.AdjacencyMatrix.WeightedGraph-2.html
│ ├── Advanced.Algorithms.DataStructures.Graph.AdjacencyMatrix.html
│ ├── Advanced.Algorithms.DataStructures.Graph.IDiEdge-1.html
│ ├── Advanced.Algorithms.DataStructures.Graph.IDiGraph-1.html
│ ├── Advanced.Algorithms.DataStructures.Graph.IDiGraphVertex-1.html
│ ├── Advanced.Algorithms.DataStructures.Graph.IEdge-1.html
│ ├── Advanced.Algorithms.DataStructures.Graph.IGraph-1.html
│ ├── Advanced.Algorithms.DataStructures.Graph.IGraphVertex-1.html
│ ├── Advanced.Algorithms.DataStructures.Graph.html
│ ├── Advanced.Algorithms.DataStructures.HashSet-1.html
│ ├── Advanced.Algorithms.DataStructures.HashSetNode-1.html
│ ├── Advanced.Algorithms.DataStructures.HashSetType.html
│ ├── Advanced.Algorithms.DataStructures.HashSets.HashSet-1.html
│ ├── Advanced.Algorithms.DataStructures.HashSets.HashSetNode-1.html
│ ├── Advanced.Algorithms.DataStructures.HashSets.HashSetType.html
│ ├── Advanced.Algorithms.DataStructures.HashSets.SortedHashSet-1.html
│ ├── Advanced.Algorithms.DataStructures.HashSets.html
│ ├── Advanced.Algorithms.DataStructures.IBSTNode-1.html
│ ├── Advanced.Algorithms.DataStructures.IDistanceCalculator-1.html
│ ├── Advanced.Algorithms.DataStructures.Interval-1.html
│ ├── Advanced.Algorithms.DataStructures.IntervalTree-1.html
│ ├── Advanced.Algorithms.DataStructures.KDTree-1.html
│ ├── Advanced.Algorithms.DataStructures.MaxPriorityQueue-1.html
│ ├── Advanced.Algorithms.DataStructures.MinPriorityQueue-1.html
│ ├── Advanced.Algorithms.DataStructures.OpenAddressDictionaryEnumerator-2.html
│ ├── Advanced.Algorithms.DataStructures.OpenAddressHashSetEnumerator-1.html
│ ├── Advanced.Algorithms.DataStructures.PairingHeap-1.html
│ ├── Advanced.Algorithms.DataStructures.PairingHeapNode-1.html
│ ├── Advanced.Algorithms.DataStructures.PairingMaxHeap-1.html
│ ├── Advanced.Algorithms.DataStructures.PairingMinHeap-1.html
│ ├── Advanced.Algorithms.DataStructures.PriorityQueue-1.html
│ ├── Advanced.Algorithms.DataStructures.QuadTree-1.html
│ ├── Advanced.Algorithms.DataStructures.Queue-1.html
│ ├── Advanced.Algorithms.DataStructures.QueueType.html
│ ├── Advanced.Algorithms.DataStructures.RTree.html
│ ├── Advanced.Algorithms.DataStructures.RangeTree-1.html
│ ├── Advanced.Algorithms.DataStructures.RedBlackTree-1.html
│ ├── Advanced.Algorithms.DataStructures.SegmentTree-1.html
│ ├── Advanced.Algorithms.DataStructures.SeparateChainingDictionaryEnumerator-2.html
│ ├── Advanced.Algorithms.DataStructures.SeparateChainingHashSetEnumerator-1.html
│ ├── Advanced.Algorithms.DataStructures.SinglyLinkedList-1.html
│ ├── Advanced.Algorithms.DataStructures.SinglyLinkedListNode-1.html
│ ├── Advanced.Algorithms.DataStructures.SkipList-1.html
│ ├── Advanced.Algorithms.DataStructures.SortedDictionary-2.html
│ ├── Advanced.Algorithms.DataStructures.SortedHashSet-1.html
│ ├── Advanced.Algorithms.DataStructures.SparseSet.html
│ ├── Advanced.Algorithms.DataStructures.SplayTree-1.html
│ ├── Advanced.Algorithms.DataStructures.Stack-1.html
│ ├── Advanced.Algorithms.DataStructures.StackType.html
│ ├── Advanced.Algorithms.DataStructures.SuffixTree-1.html
│ ├── Advanced.Algorithms.DataStructures.TernarySearchTree-1.html
│ ├── Advanced.Algorithms.DataStructures.TreapTree-1.html
│ ├── Advanced.Algorithms.DataStructures.Tree-1.html
│ ├── Advanced.Algorithms.DataStructures.Tree.QuadTree-1.html
│ ├── Advanced.Algorithms.DataStructures.Tree.html
│ ├── Advanced.Algorithms.DataStructures.TreeDictionary-2.html
│ ├── Advanced.Algorithms.DataStructures.TreeDictionaryNode-2.html
│ ├── Advanced.Algorithms.DataStructures.TreeHashSet-1.html
│ ├── Advanced.Algorithms.DataStructures.TreeNode-1.html
│ ├── Advanced.Algorithms.DataStructures.Trie-1.html
│ ├── Advanced.Algorithms.DataStructures.html
│ ├── Advanced.Algorithms.Distributed.AsyncQueue-1.html
│ ├── Advanced.Algorithms.Distributed.CircularQueue-1.html
│ ├── Advanced.Algorithms.Distributed.ConsistentHash-1.html
│ ├── Advanced.Algorithms.Distributed.LRUCache-2.html
│ ├── Advanced.Algorithms.Distributed.html
│ ├── Advanced.Algorithms.Geometry.BentleyOttmann.html
│ ├── Advanced.Algorithms.Geometry.ClosestPointPair.html
│ ├── Advanced.Algorithms.Geometry.ConvexHull.html
│ ├── Advanced.Algorithms.Geometry.Line.html
│ ├── Advanced.Algorithms.Geometry.LineExtensions.html
│ ├── Advanced.Algorithms.Geometry.LineIntersection.html
│ ├── Advanced.Algorithms.Geometry.Point.html
│ ├── Advanced.Algorithms.Geometry.PointComparer.html
│ ├── Advanced.Algorithms.Geometry.PointInsidePolygon.html
│ ├── Advanced.Algorithms.Geometry.PointRotation.html
│ ├── Advanced.Algorithms.Geometry.Polygon.html
│ ├── Advanced.Algorithms.Geometry.Rectangle.html
│ ├── Advanced.Algorithms.Geometry.RectangleComparer.html
│ ├── Advanced.Algorithms.Geometry.RectangleIntersection.html
│ ├── Advanced.Algorithms.Geometry.html
│ ├── Advanced.Algorithms.Graph.AStarShortestPath-2.html
│ ├── Advanced.Algorithms.Graph.AllPairShortestPathResult-2.html
│ ├── Advanced.Algorithms.Graph.BellmanFordShortestPath-2.html
│ ├── Advanced.Algorithms.Graph.BiDirectional-1.html
│ ├── Advanced.Algorithms.Graph.BiPartiteMatching-1.html
│ ├── Advanced.Algorithms.Graph.BreadthFirst-1.html
│ ├── Advanced.Algorithms.Graph.Bridge-1.html
│ ├── Advanced.Algorithms.Graph.CycleDetector-1.html
│ ├── Advanced.Algorithms.Graph.DepthFirst-1.html
│ ├── Advanced.Algorithms.Graph.DepthFirstTopSort-1.html
│ ├── Advanced.Algorithms.Graph.DijikstraShortestPath-2.html
│ ├── Advanced.Algorithms.Graph.EdmondKarpMaxFlow-2.html
│ ├── Advanced.Algorithms.Graph.FloydWarshallShortestPath-2.html
│ ├── Advanced.Algorithms.Graph.FordFulkersonMaxFlow-2.html
│ ├── Advanced.Algorithms.Graph.HopcroftKarpMatching-1.html
│ ├── Advanced.Algorithms.Graph.IAStarHeuristic-2.html
│ ├── Advanced.Algorithms.Graph.IBiPartiteMatchOperators-1.html
│ ├── Advanced.Algorithms.Graph.IFlowOperators-1.html
│ ├── Advanced.Algorithms.Graph.IJohnsonsShortestPathOperators-2.html
│ ├── Advanced.Algorithms.Graph.IShortestPathOperators-1.html
│ ├── Advanced.Algorithms.Graph.JohnsonsShortestPath-2.html
│ ├── Advanced.Algorithms.Graph.KahnsTopSort-1.html
│ ├── Advanced.Algorithms.Graph.KosarajuStronglyConnected-1.html
│ ├── Advanced.Algorithms.Graph.Kruskals-2.html
│ ├── Advanced.Algorithms.Graph.MColorResult-2.html
│ ├── Advanced.Algorithms.Graph.MColorer-2.html
│ ├── Advanced.Algorithms.Graph.MSTEdge-2.html
│ ├── Advanced.Algorithms.Graph.MatchEdge-1.html
│ ├── Advanced.Algorithms.Graph.MinCut-2.html
│ ├── Advanced.Algorithms.Graph.MinCutEdge-1.html
│ ├── Advanced.Algorithms.Graph.MinVertexCover-1.html
│ ├── Advanced.Algorithms.Graph.Prims-2.html
│ ├── Advanced.Algorithms.Graph.PushRelabelMaxFlow-2.html
│ ├── Advanced.Algorithms.Graph.ShortestPathResult-2.html
│ ├── Advanced.Algorithms.Graph.TarjansArticulationFinder-1.html
│ ├── Advanced.Algorithms.Graph.TarjansBiConnected-1.html
│ ├── Advanced.Algorithms.Graph.TarjansBridgeFinder-1.html
│ ├── Advanced.Algorithms.Graph.TarjansStronglyConnected-1.html
│ ├── Advanced.Algorithms.Graph.TravellingSalesman-2.html
│ ├── Advanced.Algorithms.Graph.TravellingSalesman.html
│ ├── Advanced.Algorithms.Graph.html
│ ├── Advanced.Algorithms.Miscellaneous.MatrixMultiplication.html
│ ├── Advanced.Algorithms.Miscellaneous.html
│ ├── Advanced.Algorithms.Numerical.FastExponentiation.html
│ ├── Advanced.Algorithms.Numerical.KthSmallest-1.html
│ ├── Advanced.Algorithms.Numerical.MedianStream.html
│ ├── Advanced.Algorithms.Numerical.PrimeGenerator.html
│ ├── Advanced.Algorithms.Numerical.PrimeTester.html
│ ├── Advanced.Algorithms.Numerical.html
│ ├── Advanced.Algorithms.Search.BinarySearch.html
│ ├── Advanced.Algorithms.Search.BoyerMoore-1.html
│ ├── Advanced.Algorithms.Search.QuickSelect-1.html
│ ├── Advanced.Algorithms.Search.SearchAlmostSorted.html
│ ├── Advanced.Algorithms.Search.html
│ ├── Advanced.Algorithms.SortDirection.html
│ ├── Advanced.Algorithms.Sorting.BubbleSort-1.html
│ ├── Advanced.Algorithms.Sorting.BucketSort.html
│ ├── Advanced.Algorithms.Sorting.CountingSort.html
│ ├── Advanced.Algorithms.Sorting.HeapSort-1.html
│ ├── Advanced.Algorithms.Sorting.InsertionSort-1.html
│ ├── Advanced.Algorithms.Sorting.MergeSort-1.html
│ ├── Advanced.Algorithms.Sorting.QuickSort-1.html
│ ├── Advanced.Algorithms.Sorting.RadixSort.html
│ ├── Advanced.Algorithms.Sorting.SelectionSort-1.html
│ ├── Advanced.Algorithms.Sorting.ShellSort-1.html
│ ├── Advanced.Algorithms.Sorting.SortAlmostSorted.html
│ ├── Advanced.Algorithms.Sorting.TreeSort-1.html
│ ├── Advanced.Algorithms.Sorting.html
│ ├── Advanced.Algorithms.String.KMP.html
│ ├── Advanced.Algorithms.String.ManachersPalindrome.html
│ ├── Advanced.Algorithms.String.RabinKarp.html
│ ├── Advanced.Algorithms.String.ZAlgorithm.html
│ ├── Advanced.Algorithms.String.html
│ ├── Advanced.Algorithms.html
│ └── toc.html
├── favicon.ico
├── fonts
│ ├── glyphicons-halflings-regular.eot
│ ├── glyphicons-halflings-regular.svg
│ ├── glyphicons-halflings-regular.ttf
│ ├── glyphicons-halflings-regular.woff
│ └── glyphicons-halflings-regular.woff2
├── index.json
├── logo.svg
├── search-stopwords.json
├── styles
│ ├── docfx.css
│ ├── docfx.js
│ ├── docfx.vendor.css
│ ├── docfx.vendor.js
│ ├── lunr.js
│ ├── lunr.min.js
│ ├── main.css
│ ├── main.js
│ └── search-worker.js
└── xrefmap.yml
├── omnisharp.json
├── src
├── Advanced.Algorithms.Docs.sln
├── Advanced.Algorithms.sln
└── Advanced.Algorithms
│ ├── Advanced.Algorithms.csproj
│ ├── App.config
│ ├── Binary
│ ├── BaseConversion.cs
│ ├── GCD.cs
│ └── Logarithm.cs
│ ├── Combinatorics
│ ├── Combination.cs
│ ├── Permutation.cs
│ └── Subset.cs
│ ├── Compression
│ └── HuffmanCoding.cs
│ ├── DataStructures
│ ├── Dictionary
│ │ ├── Dictionary.cs
│ │ ├── OpenAddressDictionary.cs
│ │ ├── OrderedDictionary.cs
│ │ └── SeparateChainingDictionary.cs
│ ├── Graph
│ │ ├── AdjacencyList
│ │ │ ├── DiGraph.cs
│ │ │ ├── Graph.cs
│ │ │ ├── WeightedDiGraph.cs
│ │ │ └── WeightedGraph.cs
│ │ ├── AdjacencyMatrix
│ │ │ ├── DiGraph.cs
│ │ │ ├── Graph.cs
│ │ │ ├── WeightedDiGraph.cs
│ │ │ └── WeightedGraph.cs
│ │ ├── IDiGraph.cs
│ │ └── IGraph.cs
│ ├── HashSet
│ │ ├── HashSet.cs
│ │ ├── OpenAddressHashSet.cs
│ │ ├── OrderedHashSet.cs
│ │ └── SeparateChainingHashSet.cs
│ ├── Heap
│ │ ├── BHeap.cs
│ │ ├── BinomialHeap.cs
│ │ ├── FibonacciHeap.cs
│ │ ├── PairingHeap.cs
│ │ ├── Shared
│ │ │ ├── BinomialHeapNode.cs
│ │ │ ├── FibornacciHeapNode.cs
│ │ │ └── PairingHeapNode.cs
│ │ └── d-aryHeap.cs
│ ├── LinkedList
│ │ ├── CircularLinkedList.cs
│ │ ├── DoublyLinkedList.cs
│ │ └── SinglyLinkedList.cs
│ ├── List
│ │ ├── ArrayList.cs
│ │ └── SkipList.cs
│ ├── Queues
│ │ ├── ArrayQueue.cs
│ │ ├── LinkedListQueue.cs
│ │ ├── PriorityQueue.cs
│ │ └── Queue.cs
│ ├── Set
│ │ ├── BloomFilter.cs
│ │ ├── DisJointSet.cs
│ │ └── SparseSet.cs
│ ├── Shared
│ │ └── IEnumerableExtensions.cs
│ ├── Stack
│ │ ├── ArrayStack.cs
│ │ ├── LinkedListStack.cs
│ │ └── Stack.cs
│ └── Tree
│ │ ├── AvlTree.cs
│ │ ├── B+Tree.cs
│ │ ├── BST.cs
│ │ ├── BTree.cs
│ │ ├── BinaryTree.cs
│ │ ├── FenwickTree.cs
│ │ ├── IntervalTree.cs
│ │ ├── K_DTree.cs
│ │ ├── QuadTree.cs
│ │ ├── RTree.cs
│ │ ├── RangeTree.cs
│ │ ├── RedBlackTree.cs
│ │ ├── SegmentTree.cs
│ │ ├── Shared
│ │ ├── ArrayComparer.cs
│ │ ├── BSTEnumerator.cs
│ │ ├── BSTExtensions.cs
│ │ ├── BSTHelpers.cs
│ │ └── BSTNodeBase.cs
│ │ ├── SplayTree.cs
│ │ ├── SuffixTree.cs
│ │ ├── TernarySearchTree.cs
│ │ ├── TreapTree.cs
│ │ ├── Tree.cs
│ │ └── Trie.cs
│ ├── Distributed
│ ├── AsyncQueue.cs
│ ├── CircularQueue.cs
│ ├── ConsistentHash.cs
│ └── LRUCache.cs
│ ├── Geometry
│ ├── BentleyOttmann.cs
│ ├── ClosestPointPair.cs
│ ├── ConvexHull.cs
│ ├── LineIntersection.cs
│ ├── PointInsidePolygon.cs
│ ├── PointRotation.cs
│ ├── RectangleIntersection.cs
│ ├── Shapes
│ │ ├── Line.cs
│ │ ├── Point.cs
│ │ ├── Polygon.cs
│ │ └── Rectangle.cs
│ └── Shared
│ │ ├── DoubleExtensions.cs
│ │ ├── PointComparer.cs
│ │ └── RectangleComparer.cs
│ ├── Graph
│ ├── ArticulationPoint
│ │ └── TarjansArticulationFinder.cs
│ ├── Bridge
│ │ └── TarjansBridgeFinder.cs
│ ├── Coloring
│ │ └── MColorer.cs
│ ├── Connectivity
│ │ ├── KosarajuStronglyConnected.cs
│ │ ├── TarjansBiConnected.cs
│ │ └── TarjansStronglyConnected.cs
│ ├── Cover
│ │ └── MinVertexCover.cs
│ ├── Cut
│ │ └── MinimumCut.cs
│ ├── Cycle
│ │ └── CycleDetection.cs
│ ├── Flow
│ │ ├── EdmondsKarp.cs
│ │ ├── FordFulkerson.cs
│ │ └── PushRelabel.cs
│ ├── Matching
│ │ ├── BiPartiteMatching.cs
│ │ └── HopcroftKarp.cs
│ ├── MinimumSpanningTree
│ │ ├── Kruskals.cs
│ │ └── Prims.cs
│ ├── Search
│ │ ├── BiDirectional.cs
│ │ ├── BreadthFirst.cs
│ │ └── DepthFirst.cs
│ ├── ShortestPath
│ │ ├── AStar.cs
│ │ ├── Bellman-Ford.cs
│ │ ├── Dijikstra.cs
│ │ ├── Floyd-Warshall.cs
│ │ ├── Johnsons.cs
│ │ └── TravellingSalesman.cs
│ └── Sort
│ │ ├── DepthFirstTopSort.cs
│ │ └── KahnTopSort.cs
│ ├── Numerical
│ ├── Exponentiation.cs
│ ├── PrimeGenerator.cs
│ └── PrimeTester.cs
│ ├── Properties
│ └── AssemblyInfo.cs
│ ├── Search
│ ├── BinarySearch.cs
│ ├── BoyerMoore.cs
│ └── QuickSelect.cs
│ ├── Shared
│ ├── CustomComparer.cs
│ └── SortDirection.cs
│ ├── Sorting
│ ├── BubbleSort.cs
│ ├── BucketSort.cs
│ ├── CountingSort.cs
│ ├── HeapSort.cs
│ ├── InsertionSort.cs
│ ├── MergeSort.cs
│ ├── QuickSort.cs
│ ├── RadixSort.cs
│ ├── SelectionSort.cs
│ ├── ShellSort.cs
│ └── TreeSort.cs
│ ├── String
│ ├── ManachersPalindrome.cs
│ └── Search
│ │ ├── KMP.cs
│ │ ├── RabinKarp.cs
│ │ └── ZAlgorithm.cs
│ └── StrongNameKey.snk
└── tests
├── Advanced.Algorithms.Tests
├── Advanced.Algorithms.Tests.Mono.csproj
├── Advanced.Algorithms.Tests.NetCore.csproj
├── Advanced.Algorithms.Tests.csproj
├── Binary
│ ├── BaseConversion_Tests.cs
│ ├── GCD_Tests.cs
│ └── Logarithm_Tests.cs
├── Combinatorics
│ ├── Combination_Tests.cs
│ ├── Permutation_Tests.cs
│ └── Subset_Tests.cs
├── Compression
│ └── HuffmanCoding_Tests.cs
├── DataStructures
│ ├── Dictionary
│ │ ├── Dictionary_Tests.cs
│ │ └── OrderedDictionary_Tests.cs
│ ├── Graph
│ │ ├── AdjacencyList
│ │ │ ├── DiGraph_Tests.cs
│ │ │ ├── Graph_Tests.cs
│ │ │ ├── WeightedDiGraph_Tests.cs
│ │ │ └── WeightedGraph_Tests.cs
│ │ └── AdjacencyMatrix
│ │ │ ├── DiGraph_Tests.cs
│ │ │ ├── Graph_Tests.cs
│ │ │ ├── WeightedDiGraph_Tests.cs
│ │ │ └── WeightedGraph_Tests.cs
│ ├── HashSet
│ │ ├── HashSet_Tests.cs
│ │ └── OrderedHashSet_Tests.cs
│ ├── Heap
│ │ ├── BHeap_Tests.cs
│ │ ├── BinomialHeap_Tests.cs
│ │ ├── D-aryHeap_Tests.cs
│ │ ├── FibonacciHeap_Tests.cs
│ │ └── PairingHeap_Tests.cs
│ ├── LinkedList
│ │ ├── CircularLinkedList_Tests.cs
│ │ ├── DoublyLinkedList_Tests.cs
│ │ └── SinglyLinkedList_Tests.cs
│ ├── Lists
│ │ ├── ArrayList_Tests.cs
│ │ └── SkipList_Tests.cs
│ ├── Queues
│ │ ├── PriorityQueue_Tests.cs
│ │ └── Queue_Tests.cs
│ ├── Set
│ │ ├── BloomFilter_Tests.cs
│ │ ├── DisJointSet_Tests.cs
│ │ └── SparseSet_Tests.cs
│ ├── Stack_Tests.cs
│ └── Tree
│ │ ├── AVLTree_Tests.cs
│ │ ├── B+Tree_Tests.cs
│ │ ├── BST_Tests.cs
│ │ ├── BTree_Tests.cs
│ │ ├── BinaryTree_Tests.cs
│ │ ├── FenwickTree_Tests.cs
│ │ ├── IntervalTree_Tests.cs
│ │ ├── KdTree_Tests.cs
│ │ ├── QuadTree_Tests.cs
│ │ ├── RTree_Tests.cs
│ │ ├── RangeTreeTests.cs
│ │ ├── RedBlackTree_Tests.cs
│ │ ├── SegmentTree_Tests.cs
│ │ ├── SplayTree_Tests.cs
│ │ ├── SuffixTree_Tests.cs
│ │ ├── TernarySearchTree_Tests.cs
│ │ ├── TestHelpers
│ │ ├── BSTTester.cs
│ │ └── BTreeTester.cs
│ │ ├── TreapTree_Tests.cs
│ │ ├── Tree_Tests.cs
│ │ └── Trie_Tests.cs
├── Distributed
│ ├── AsyncQueue_Tests.cs
│ ├── CircularQueue_Tests.cs
│ ├── ConsistentHash_Tests.cs
│ └── LRUCache_Tests.cs
├── Geometry
│ ├── BentleyOttmann_Tests.cs
│ ├── ClosestPointPair_Tests.cs
│ ├── ConvexHull_Tests.cs
│ ├── LineIntersection_Tests.cs
│ ├── PointInsidePolygon_Tests.cs
│ ├── PointRotation_Tests.cs
│ └── RectangleIntersection_Tests.cs
├── Graph
│ ├── ArticulationPoints
│ │ └── TarjansArticulation_Tests.cs
│ ├── Bridge
│ │ └── TarjansBridge_Tests.cs
│ ├── Coloring
│ │ └── MColoring_Tests.cs
│ ├── Connectivity
│ │ ├── KosarajuStronglyConnected_Tests.cs
│ │ ├── TarjansBiConnected_Tests.cs
│ │ └── TarjansStronglyConnected_Tests.cs
│ ├── Cover
│ │ └── MinVertexCover.cs
│ ├── Cut
│ │ └── MinCut_Tests.cs
│ ├── Cycle
│ │ └── CycleDetection_Tests.cs
│ ├── Flow
│ │ ├── EdmondsKarp_Tests.cs
│ │ ├── FordFulkerson_Tests.cs
│ │ └── PushRelabel_Tests.cs
│ ├── Matching
│ │ ├── BiPartiteMatching_Tests.cs
│ │ └── HopcroftKarp_Tests.cs
│ ├── MinimumSpanningTree
│ │ ├── Kruskals_Test.cs
│ │ └── Prims_Test.cs
│ ├── Search
│ │ ├── BiDirectional_Tests.cs
│ │ ├── BreadthFirst_Tests.cs
│ │ └── DepthFirst_Tests.cs
│ ├── ShortestPath
│ │ ├── AStar_Tests.cs
│ │ ├── BellmanFord_Tests.cs
│ │ ├── Dijikstras_Tests.cs
│ │ ├── FloydWarshall_Tests.cs
│ │ ├── Johnson_Tests.cs
│ │ └── TravellingSalesman_Tests.cs
│ └── Sort
│ │ ├── DepthFirstTopSort_Tests.cs
│ │ └── KahnTopSort_Tests.cs
├── Numerical
│ ├── Exponentiation_Tests.cs
│ ├── Primality_Tests.cs
│ └── PrimeGenerator_Tests.cs
├── Properties
│ └── AssemblyInfo.cs
├── Search
│ ├── BinarySearch_Tests.cs
│ ├── BoyerMoore_Tests.cs
│ └── QuickSelect_Tests.cs
├── Sorting
│ ├── BubbleSort_Tests.cs
│ ├── BucketSort_Tests.cs
│ ├── CountingSort_Tests.cs
│ ├── HeapSort_Tests.cs
│ ├── InsertionSort_Tests.cs
│ ├── MergeSort_Tests.cs
│ ├── QuickSort_Tests.cs
│ ├── RadixSort_Tests.cs
│ ├── SelectionSort_Tests.cs
│ ├── ShellSort_Tests.cs
│ └── TreeSort_Tests.cs
├── String
│ ├── Manachers_Tests.cs
│ └── Search
│ │ ├── KMP_Tests.cs
│ │ ├── RabinKarp_Tests.cs
│ │ └── Z_Tests.cs
└── StrongNameKey.snk
└── escape.txt
/.github/docfx.json:
--------------------------------------------------------------------------------
1 | {
2 | "metadata": [
3 | {
4 | "src": [
5 | {
6 | "files": ["Advanced.Algorithms.Docs.sln"],
7 | "src": "../src/"
8 | }
9 | ],
10 | "dest": "obj/api"
11 | }
12 | ],
13 | "build": {
14 | "content": [
15 | {
16 | "files": ["**/*.yml"],
17 | "src": "obj/api",
18 | "dest": "api"
19 | },
20 | {
21 | "files": ["*.md"]
22 | }
23 | ],
24 | "resource": [
25 | {
26 | "files": [""]
27 | }
28 | ],
29 | "overwrite": "specs/*.md",
30 | "globalMetadata": {
31 | "_appTitle": "Advanced Algorithms",
32 | "_enableSearch": true
33 | },
34 | "dest": "../docs",
35 | "xrefService": ["https://xref.docs.microsoft.com/query?uid={uid}"]
36 | }
37 | }
--------------------------------------------------------------------------------
/.github/workflows/dotnetcore.yml:
--------------------------------------------------------------------------------
1 | name: .NET Core
2 |
3 | on:
4 | push:
5 | branches:
6 | - develop
7 | - beta
8 | - stable
9 | pull_request:
10 | branches:
11 | - develop
12 | - beta
13 | - stable
14 |
15 | jobs:
16 | build:
17 | runs-on: windows-latest
18 | steps:
19 | - uses: actions/checkout@v2
20 |
21 | - name: Install DocFX
22 | if: github.ref == 'refs/heads/develop'
23 | run: choco install docfx -y
24 |
25 | - name: Build
26 | run: dotnet build src/Advanced.Algorithms.sln
27 |
28 | - name: Test
29 | run: dotnet test src/Advanced.Algorithms.sln
30 |
31 | - name: Update Documentation
32 | if: github.ref == 'refs/heads/develop'
33 | run: docfx .github/docfx.json
34 |
35 | - name: Publish Documentation
36 | if: github.ref == 'refs/heads/develop'
37 | uses: EndBug/add-and-commit@v9
38 | with:
39 | default_author: github_actions
40 | message: Update documentation
41 | committer_name: GitHub Actions
42 | committer_email: actions@github.com
43 |
44 | - name: Publish Beta
45 | if: github.ref == 'refs/heads/beta'
46 | run: |
47 | dotnet pack src/Advanced.Algorithms/Advanced.Algorithms.csproj --version-suffix "beta"
48 | dotnet nuget push **\*.nupkg -s "nuget" -k "${{ secrets.NUGET_TOKEN }}"
49 |
50 | - name: Publish Stable
51 | if: github.ref == 'refs/heads/stable'
52 | run: |
53 | dotnet pack src/Advanced.Algorithms/Advanced.Algorithms.csproj
54 | dotnet nuget push **\*.nupkg -s "nuget" -k "${{ secrets.NUGET_TOKEN }}"
55 |
--------------------------------------------------------------------------------
/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | // The following will hide the js and map files in the editor
3 | "files.exclude": {
4 | "**/.build": true,
5 | "**/.nuget": true,
6 | "**/.vs": true,
7 | "**/docs": true,
8 | "**/packages": true,
9 | "**/bin": true,
10 | "**/obj": true,
11 | "**/*.DotSettings": true,
12 | "**/*.sln": true,
13 | "**/*.Mono.csproj": true,
14 | "**/*.Docs.csproj": true,
15 | "**/*.Algorithms.csproj": true,
16 | "**/*.Tests.csproj": true
17 | },
18 | "search.exclude": {
19 | "**/.build": true,
20 | "**/.nuget": true,
21 | "**/.vs": true,
22 | "**/docs": true,
23 | "**/packages": true,
24 | "**/bin": true,
25 | "**/obj": true,
26 | "**/*.DotSettings": true,
27 | "**/*.sln": true,
28 | "**/*.Mono.csproj": true,
29 | "**/*.Docs.csproj": true,
30 | "**/*.Algorithms.csproj": true,
31 | "**/*.Tests.csproj": true
32 | }
33 | }
--------------------------------------------------------------------------------
/.vscode/tasks.json:
--------------------------------------------------------------------------------
1 | {
2 | "version": "2.0.0",
3 | "tasks": [
4 | {
5 | "label": "build",
6 | "type": "process",
7 | "command": "dotnet",
8 | "args": ["build","${workspaceFolder}/src/Advanced.Algorithms.NetCore.sln"],
9 | "problemMatcher": "$msCompile",
10 | "group": {
11 | "kind": "build",
12 | "isDefault": true
13 | }
14 | }
15 | ]
16 | }
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2016 Jehonathan
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/NuGet.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/PULL_REQUEST_TEMPLATE.md:
--------------------------------------------------------------------------------
1 | - [ ] This is not a new algorithm. See readme.
2 | Doneness:
3 | - [ ] Build is okay - I made sure that this change is building successfully.
4 | - [ ] No Bugs - I made sure that this change is working properly as expected. It doesn't have any bugs that you are aware of.
5 | - [ ] Branching - If this is not a hotfix, I am making this request against develop branch
6 |
--------------------------------------------------------------------------------
/_config.yml:
--------------------------------------------------------------------------------
1 | baseurl: /Advanced-Algorithms
--------------------------------------------------------------------------------
/docs/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/justcoding121/advanced-algorithms/a7bfe1555f1a623525415ab91725a3ff26b7cf69/docs/favicon.ico
--------------------------------------------------------------------------------
/docs/fonts/glyphicons-halflings-regular.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/justcoding121/advanced-algorithms/a7bfe1555f1a623525415ab91725a3ff26b7cf69/docs/fonts/glyphicons-halflings-regular.eot
--------------------------------------------------------------------------------
/docs/fonts/glyphicons-halflings-regular.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/justcoding121/advanced-algorithms/a7bfe1555f1a623525415ab91725a3ff26b7cf69/docs/fonts/glyphicons-halflings-regular.ttf
--------------------------------------------------------------------------------
/docs/fonts/glyphicons-halflings-regular.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/justcoding121/advanced-algorithms/a7bfe1555f1a623525415ab91725a3ff26b7cf69/docs/fonts/glyphicons-halflings-regular.woff
--------------------------------------------------------------------------------
/docs/fonts/glyphicons-halflings-regular.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/justcoding121/advanced-algorithms/a7bfe1555f1a623525415ab91725a3ff26b7cf69/docs/fonts/glyphicons-halflings-regular.woff2
--------------------------------------------------------------------------------
/docs/logo.svg:
--------------------------------------------------------------------------------
1 |
2 |
4 |
26 |
--------------------------------------------------------------------------------
/docs/search-stopwords.json:
--------------------------------------------------------------------------------
1 | [
2 | "a",
3 | "able",
4 | "about",
5 | "across",
6 | "after",
7 | "all",
8 | "almost",
9 | "also",
10 | "am",
11 | "among",
12 | "an",
13 | "and",
14 | "any",
15 | "are",
16 | "as",
17 | "at",
18 | "be",
19 | "because",
20 | "been",
21 | "but",
22 | "by",
23 | "can",
24 | "cannot",
25 | "could",
26 | "dear",
27 | "did",
28 | "do",
29 | "does",
30 | "either",
31 | "else",
32 | "ever",
33 | "every",
34 | "for",
35 | "from",
36 | "get",
37 | "got",
38 | "had",
39 | "has",
40 | "have",
41 | "he",
42 | "her",
43 | "hers",
44 | "him",
45 | "his",
46 | "how",
47 | "however",
48 | "i",
49 | "if",
50 | "in",
51 | "into",
52 | "is",
53 | "it",
54 | "its",
55 | "just",
56 | "least",
57 | "let",
58 | "like",
59 | "likely",
60 | "may",
61 | "me",
62 | "might",
63 | "most",
64 | "must",
65 | "my",
66 | "neither",
67 | "no",
68 | "nor",
69 | "not",
70 | "of",
71 | "off",
72 | "often",
73 | "on",
74 | "only",
75 | "or",
76 | "other",
77 | "our",
78 | "own",
79 | "rather",
80 | "said",
81 | "say",
82 | "says",
83 | "she",
84 | "should",
85 | "since",
86 | "so",
87 | "some",
88 | "than",
89 | "that",
90 | "the",
91 | "their",
92 | "them",
93 | "then",
94 | "there",
95 | "these",
96 | "they",
97 | "this",
98 | "tis",
99 | "to",
100 | "too",
101 | "twas",
102 | "us",
103 | "wants",
104 | "was",
105 | "we",
106 | "were",
107 | "what",
108 | "when",
109 | "where",
110 | "which",
111 | "while",
112 | "who",
113 | "whom",
114 | "why",
115 | "will",
116 | "with",
117 | "would",
118 | "yet",
119 | "you",
120 | "your"
121 | ]
122 |
--------------------------------------------------------------------------------
/docs/styles/main.css:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/justcoding121/advanced-algorithms/a7bfe1555f1a623525415ab91725a3ff26b7cf69/docs/styles/main.css
--------------------------------------------------------------------------------
/docs/styles/main.js:
--------------------------------------------------------------------------------
1 | // Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license. See LICENSE file in the project root for full license information.
2 |
--------------------------------------------------------------------------------
/docs/styles/search-worker.js:
--------------------------------------------------------------------------------
1 | (function () {
2 | importScripts('lunr.min.js');
3 |
4 | var lunrIndex;
5 |
6 | var stopWords = null;
7 | var searchData = {};
8 |
9 | lunr.tokenizer.separator = /[\s\-\.\(\)]+/;
10 |
11 | var stopWordsRequest = new XMLHttpRequest();
12 | stopWordsRequest.open('GET', '../search-stopwords.json');
13 | stopWordsRequest.onload = function () {
14 | if (this.status != 200) {
15 | return;
16 | }
17 | stopWords = JSON.parse(this.responseText);
18 | buildIndex();
19 | }
20 | stopWordsRequest.send();
21 |
22 | var searchDataRequest = new XMLHttpRequest();
23 |
24 | searchDataRequest.open('GET', '../index.json');
25 | searchDataRequest.onload = function () {
26 | if (this.status != 200) {
27 | return;
28 | }
29 | searchData = JSON.parse(this.responseText);
30 |
31 | buildIndex();
32 |
33 | postMessage({ e: 'index-ready' });
34 | }
35 | searchDataRequest.send();
36 |
37 | onmessage = function (oEvent) {
38 | var q = oEvent.data.q;
39 | var hits = lunrIndex.search(q);
40 | var results = [];
41 | hits.forEach(function (hit) {
42 | var item = searchData[hit.ref];
43 | results.push({ 'href': item.href, 'title': item.title, 'keywords': item.keywords });
44 | });
45 | postMessage({ e: 'query-ready', q: q, d: results });
46 | }
47 |
48 | function buildIndex() {
49 | if (stopWords !== null && !isEmpty(searchData)) {
50 | lunrIndex = lunr(function () {
51 | this.pipeline.remove(lunr.stopWordFilter);
52 | this.ref('href');
53 | this.field('title', { boost: 50 });
54 | this.field('keywords', { boost: 20 });
55 |
56 | for (var prop in searchData) {
57 | if (searchData.hasOwnProperty(prop)) {
58 | this.add(searchData[prop]);
59 | }
60 | }
61 |
62 | var docfxStopWordFilter = lunr.generateStopWordFilter(stopWords);
63 | lunr.Pipeline.registerFunction(docfxStopWordFilter, 'docfxStopWordFilter');
64 | this.pipeline.add(docfxStopWordFilter);
65 | this.searchPipeline.add(docfxStopWordFilter);
66 | });
67 | }
68 | }
69 |
70 | function isEmpty(obj) {
71 | if(!obj) return true;
72 |
73 | for (var prop in obj) {
74 | if (obj.hasOwnProperty(prop))
75 | return false;
76 | }
77 |
78 | return true;
79 | }
80 | })();
81 |
--------------------------------------------------------------------------------
/omnisharp.json:
--------------------------------------------------------------------------------
1 | {
2 | "fileOptions": {
3 | "excludeSearchPatterns": [
4 | "**/*.Docs.csproj",
5 | "**/*.DotSettings",
6 | "**/*.sln",
7 | "**/*.Mono.csproj",
8 | "**/*.Docs.csproj",
9 | "**/*.Algorithms.csproj",
10 | "**/*.Tests.csproj"
11 | ]
12 | }
13 | }
--------------------------------------------------------------------------------
/src/Advanced.Algorithms.Docs.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio Version 16
4 | VisualStudioVersion = 16.0.30621.155
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Advanced.Algorithms", "Advanced.Algorithms\Advanced.Algorithms.csproj", "{C0BE46BB-2E54-43D2-953D-728D9B96B52A}"
7 | EndProject
8 | Global
9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
10 | Debug|Any CPU = Debug|Any CPU
11 | Release|Any CPU = Release|Any CPU
12 | EndGlobalSection
13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
14 | {C0BE46BB-2E54-43D2-953D-728D9B96B52A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
15 | {C0BE46BB-2E54-43D2-953D-728D9B96B52A}.Debug|Any CPU.Build.0 = Debug|Any CPU
16 | {C0BE46BB-2E54-43D2-953D-728D9B96B52A}.Release|Any CPU.ActiveCfg = Release|Any CPU
17 | {C0BE46BB-2E54-43D2-953D-728D9B96B52A}.Release|Any CPU.Build.0 = Release|Any CPU
18 | EndGlobalSection
19 | GlobalSection(SolutionProperties) = preSolution
20 | HideSolutionNode = FALSE
21 | EndGlobalSection
22 | GlobalSection(ExtensibilityGlobals) = postSolution
23 | SolutionGuid = {A250E1E5-3ABA-4FED-9A0E-6C63EB0261E0}
24 | EndGlobalSection
25 | EndGlobal
26 |
--------------------------------------------------------------------------------
/src/Advanced.Algorithms.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio Version 17
4 | VisualStudioVersion = 17.1.32228.430
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Documentation", "Documentation", "{38EA62D0-D2CB-465D-AF4F-407C5B4D4A1E}"
7 | ProjectSection(SolutionItems) = preProject
8 | ..\LICENSE = ..\LICENSE
9 | ..\README.md = ..\README.md
10 | EndProjectSection
11 | EndProject
12 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Build", "Build", "{AC9AE37A-3059-4FDB-9A5C-363AD86F2EEF}"
13 | ProjectSection(SolutionItems) = preProject
14 | ..\.github\docfx.json = ..\.github\docfx.json
15 | ..\.github\workflows\dotnetcore.yml = ..\.github\workflows\dotnetcore.yml
16 | EndProjectSection
17 | EndProject
18 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Advanced.Algorithms", "Advanced.Algorithms\Advanced.Algorithms.csproj", "{32E22D53-CECD-4E2D-ADAD-85DD79A8549F}"
19 | EndProject
20 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Advanced.Algorithms.Tests", "..\tests\Advanced.Algorithms.Tests\Advanced.Algorithms.Tests.csproj", "{556705BD-1E64-426D-A9CA-08390156FB85}"
21 | EndProject
22 | Global
23 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
24 | Debug|Any CPU = Debug|Any CPU
25 | Release|Any CPU = Release|Any CPU
26 | EndGlobalSection
27 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
28 | {32E22D53-CECD-4E2D-ADAD-85DD79A8549F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
29 | {32E22D53-CECD-4E2D-ADAD-85DD79A8549F}.Debug|Any CPU.Build.0 = Debug|Any CPU
30 | {32E22D53-CECD-4E2D-ADAD-85DD79A8549F}.Release|Any CPU.ActiveCfg = Release|Any CPU
31 | {32E22D53-CECD-4E2D-ADAD-85DD79A8549F}.Release|Any CPU.Build.0 = Release|Any CPU
32 | {556705BD-1E64-426D-A9CA-08390156FB85}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
33 | {556705BD-1E64-426D-A9CA-08390156FB85}.Debug|Any CPU.Build.0 = Debug|Any CPU
34 | {556705BD-1E64-426D-A9CA-08390156FB85}.Release|Any CPU.ActiveCfg = Release|Any CPU
35 | {556705BD-1E64-426D-A9CA-08390156FB85}.Release|Any CPU.Build.0 = Release|Any CPU
36 | EndGlobalSection
37 | GlobalSection(SolutionProperties) = preSolution
38 | HideSolutionNode = FALSE
39 | EndGlobalSection
40 | GlobalSection(ExtensibilityGlobals) = postSolution
41 | SolutionGuid = {625C1EB5-44CF-47DE-A85A-B4C8C40ED90A}
42 | EnterpriseLibraryConfigurationToolBinariesPath = .1.505.2\lib\NET35
43 | EndGlobalSection
44 | EndGlobal
45 |
--------------------------------------------------------------------------------
/src/Advanced.Algorithms/Advanced.Algorithms.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | net451;netstandard1.0
5 | Advanced.Algorithms
6 | false
7 | True
8 | StrongNameKey.snk
9 | False
10 | True
11 | latest
12 | 1.0.0.0
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/src/Advanced.Algorithms/App.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/src/Advanced.Algorithms/Binary/GCD.cs:
--------------------------------------------------------------------------------
1 | namespace Advanced.Algorithms.Binary;
2 |
3 | ///
4 | /// GCD without division or mod operators but using substraction.
5 | ///
6 | public class Gcd
7 | {
8 | public static int Find(int a, int b)
9 | {
10 | if (b == 0) return a;
11 |
12 | if (a == 0) return b;
13 |
14 | //fix negative numbers
15 | if (a < 0) a = -a;
16 |
17 | if (b < 0) b = -b;
18 |
19 | // p and q even
20 | if ((a & 1) == 0 && (b & 1) == 0)
21 | //divide both a and b by 2
22 | //multiply by 2 the result
23 | return Find(a >> 1, b >> 1) << 1;
24 |
25 | // a is even, b is odd
26 |
27 | if ((a & 1) == 0)
28 | //divide a by 2
29 | return Find(a >> 1, b);
30 |
31 | // a is odd, b is even
32 | if ((b & 1) == 0)
33 | //divide by by 2
34 | return Find(a, b >> 1);
35 | // a and b odd, a >= b
36 |
37 | if (a >= b)
38 | //since substracting two odd numbers gives an even number
39 | //divide (a-b) by 2 to reduce calculations
40 | return Find((a - b) >> 1, b);
41 | // a and b odd, a < b
42 |
43 | //since substracting two odd numbers gives an even number
44 | //divide (b-a) by 2 to reduce calculations
45 | return Find(a, (b - a) >> 1);
46 | }
47 | }
--------------------------------------------------------------------------------
/src/Advanced.Algorithms/Binary/Logarithm.cs:
--------------------------------------------------------------------------------
1 | namespace Advanced.Algorithms.Binary;
2 |
3 | ///
4 | /// Logarithm calculator.
5 | ///
6 | public class Logarithm
7 | {
8 | public static int CalcBase2LogFloor(int x)
9 | {
10 | //make all right most bits after MSB to 1s
11 | //for example make ..001000 => ..001111
12 | x = x | (x >> 1);
13 | x = x | (x >> 2);
14 | x = x | (x >> 4);
15 | x = x | (x >> 8);
16 | x = x | (x >> 16);
17 |
18 | //now log(x) base 2 = count the number of set bits - 1
19 | //to find the count do the following steps
20 |
21 | //set bit count of 2 bit groups
22 | //0x0555.. will be like 010101010101..
23 | x = (x & 0x55555555) + ((x >> 1) & 0x55555555);
24 |
25 | //set bit count of 4 bit groups
26 | //0x0333.. will be like 001100110011..
27 | x = (x & 0x33333333) + ((x >> 2) & 0x33333333);
28 |
29 | //set bit count of 8 bit groups of 4
30 | //0x0f0f.. will be like 0000111100001111..
31 | x = (x & 0x0F0F0F0F) + ((x >> 4) & 0x0F0F0F0F);
32 |
33 | //sum up the four groups of 8 bit
34 | x = (x & 0x000000FF)
35 | + ((x >> 8) & 0x000000FF)
36 | + ((x >> 16) & 0x000000FF)
37 | + ((x >> 24) & 0x000000FF);
38 |
39 | //-1 for log of base 2
40 | return x - 1;
41 | }
42 |
43 | public static int CalcBase10LogFloor(int x)
44 | {
45 | //using the below relation
46 | //log(x) base b = (log(x) base a) / (log(b) base a)
47 | var n = CalcBase2LogFloor(x);
48 | var d = CalcBase2LogFloor(10);
49 |
50 | return n / d;
51 | }
52 | }
--------------------------------------------------------------------------------
/src/Advanced.Algorithms/Combinatorics/Combination.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 |
3 | namespace Advanced.Algorithms.Combinatorics;
4 |
5 | ///
6 | /// Combination generator (nCr).
7 | ///
8 | public class Combination
9 | {
10 | public static List> Find(List n, int r, bool withRepetition = false)
11 | {
12 | var result = new List>();
13 |
14 | Recurse(n, r, withRepetition, 0, new List(), new HashSet(), result);
15 |
16 | return result;
17 | }
18 |
19 | private static void Recurse(List n, int r, bool withRepetition,
20 | int k, List prefix, HashSet prefixIndices,
21 | List> result)
22 | {
23 | if (prefix.Count == r)
24 | {
25 | result.Add(new List(prefix));
26 | return;
27 | }
28 |
29 | for (var j = k; j < n.Count; j++)
30 | {
31 | if (prefixIndices.Contains(j) && !withRepetition) continue;
32 |
33 | prefix.Add(n[j]);
34 | prefixIndices.Add(j);
35 |
36 | Recurse(n, r, withRepetition, j, prefix, prefixIndices, result);
37 |
38 | prefix.RemoveAt(prefix.Count - 1);
39 | prefixIndices.Remove(j);
40 | }
41 | }
42 | }
--------------------------------------------------------------------------------
/src/Advanced.Algorithms/Combinatorics/Permutation.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 |
3 | namespace Advanced.Algorithms.Combinatorics;
4 |
5 | ///
6 | /// Permutation generator (nPr).
7 | ///
8 | public class Permutation
9 | {
10 | public static List> Find(List n, int r, bool withRepetition = false)
11 | {
12 | var result = new List>();
13 |
14 | Recurse(n, r, withRepetition, new List(), new HashSet(), result);
15 |
16 | return result;
17 | }
18 |
19 | private static void Recurse(List n, int r, bool withRepetition,
20 | List prefix, HashSet prefixIndices,
21 | List> result)
22 | {
23 | if (prefix.Count == r)
24 | {
25 | result.Add(new List(prefix));
26 | return;
27 | }
28 |
29 | for (var j = 0; j < n.Count; j++)
30 | {
31 | if (prefixIndices.Contains(j) && !withRepetition) continue;
32 |
33 | prefix.Add(n[j]);
34 | prefixIndices.Add(j);
35 |
36 | Recurse(n, r, withRepetition, prefix, prefixIndices, result);
37 |
38 | prefix.RemoveAt(prefix.Count - 1);
39 | prefixIndices.Remove(j);
40 | }
41 | }
42 | }
--------------------------------------------------------------------------------
/src/Advanced.Algorithms/Combinatorics/Subset.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 |
3 | namespace Advanced.Algorithms.Combinatorics;
4 |
5 | ///
6 | /// Subset generator.
7 | ///
8 | public class Subset
9 | {
10 | public static List> Find(List input)
11 | {
12 | var result = new List>();
13 |
14 | Recurse(input, 0, new List(), new HashSet(), result);
15 |
16 | return result;
17 | }
18 |
19 | private static void Recurse(List input,
20 | int k, List prefix, HashSet prefixIndices,
21 | List> result)
22 | {
23 | result.Add(new List(prefix));
24 |
25 | for (var j = k; j < input.Count; j++)
26 | {
27 | if (prefixIndices.Contains(j)) continue;
28 |
29 | prefix.Add(input[j]);
30 | prefixIndices.Add(j);
31 |
32 | Recurse(input, j + 1, prefix, prefixIndices, result);
33 |
34 | prefix.RemoveAt(prefix.Count - 1);
35 | prefixIndices.Remove(j);
36 | }
37 | }
38 | }
--------------------------------------------------------------------------------
/src/Advanced.Algorithms/DataStructures/Graph/IDiGraph.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 |
4 | namespace Advanced.Algorithms.DataStructures.Graph;
5 |
6 | ///
7 | /// Directed graph.
8 | ///
9 | ///
10 | public interface IDiGraph
11 | {
12 | bool IsWeightedGraph { get; }
13 | IDiGraphVertex ReferenceVertex { get; }
14 | IEnumerable> VerticesAsEnumberable { get; }
15 | int VerticesCount { get; }
16 |
17 | bool ContainsVertex(T value);
18 | IDiGraphVertex GetVertex(T key);
19 |
20 | bool HasEdge(T source, T destination);
21 |
22 | IDiGraph Clone();
23 | }
24 |
25 | public interface IDiGraphVertex
26 | {
27 | T Key { get; }
28 | IEnumerable> OutEdges { get; }
29 | IEnumerable> InEdges { get; }
30 |
31 | int OutEdgeCount { get; }
32 | int InEdgeCount { get; }
33 |
34 | IDiEdge GetOutEdge(IDiGraphVertex targetVertex);
35 | }
36 |
37 | public interface IDiEdge
38 | {
39 | T TargetVertexKey { get; }
40 | IDiGraphVertex TargetVertex { get; }
41 | TW Weight() where TW : IComparable;
42 | }
43 |
44 | internal class DiEdge : IDiEdge where TC : IComparable
45 | {
46 | private readonly object weight;
47 |
48 | internal DiEdge(IDiGraphVertex target, TC weight)
49 | {
50 | TargetVertex = target;
51 | this.weight = weight;
52 | }
53 |
54 | public T TargetVertexKey => TargetVertex.Key;
55 |
56 | public IDiGraphVertex TargetVertex { get; }
57 |
58 | public TW Weight() where TW : IComparable
59 | {
60 | return (TW)weight;
61 | }
62 | }
--------------------------------------------------------------------------------
/src/Advanced.Algorithms/DataStructures/Graph/IGraph.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 |
4 | namespace Advanced.Algorithms.DataStructures.Graph;
5 |
6 | ///
7 | /// UnDirected graph. (When implemented on a directed graphs only outgoing edges are considered as Edges).
8 | ///
9 | ///
10 | public interface IGraph
11 | {
12 | bool IsWeightedGraph { get; }
13 |
14 | int VerticesCount { get; }
15 | IGraphVertex ReferenceVertex { get; }
16 | IEnumerable> VerticesAsEnumberable { get; }
17 | bool ContainsVertex(T key);
18 | IGraphVertex GetVertex(T key);
19 |
20 | bool HasEdge(T source, T destination);
21 |
22 | IGraph Clone();
23 | }
24 |
25 | public interface IGraphVertex
26 | {
27 | T Key { get; }
28 | IEnumerable> Edges { get; }
29 |
30 | IEdge GetEdge(IGraphVertex targetVertex);
31 | }
32 |
33 | public interface IEdge
34 | {
35 | T TargetVertexKey { get; }
36 | IGraphVertex TargetVertex { get; }
37 | TW Weight() where TW : IComparable;
38 | }
39 |
40 | internal class Edge : IEdge where TC : IComparable
41 | {
42 | private readonly object weight;
43 |
44 | internal Edge(IGraphVertex target, TC weight)
45 | {
46 | TargetVertex = target;
47 | this.weight = weight;
48 | }
49 |
50 | public T TargetVertexKey => TargetVertex.Key;
51 |
52 | public IGraphVertex TargetVertex { get; }
53 |
54 | public TW Weight() where TW : IComparable
55 | {
56 | return (TW)weight;
57 | }
58 | }
--------------------------------------------------------------------------------
/src/Advanced.Algorithms/DataStructures/Heap/Shared/BinomialHeapNode.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 |
4 | namespace Advanced.Algorithms.DataStructures;
5 |
6 | internal class BinomialHeapNode : IComparable where T : IComparable
7 | {
8 | internal BinomialHeapNode(T value)
9 | {
10 | Value = value;
11 |
12 | Children = new List>();
13 | }
14 |
15 | internal T Value { get; set; }
16 | internal int Degree => Children.Count;
17 |
18 | internal BinomialHeapNode Parent { get; set; }
19 | internal List> Children { get; set; }
20 |
21 | public int CompareTo(object obj)
22 | {
23 | return Value.CompareTo(((BinomialHeapNode)obj).Value);
24 | }
25 | }
--------------------------------------------------------------------------------
/src/Advanced.Algorithms/DataStructures/Heap/Shared/FibornacciHeapNode.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace Advanced.Algorithms.DataStructures;
4 |
5 | internal class FibonacciHeapNode : IComparable where T : IComparable
6 | {
7 | internal int Degree;
8 | internal FibonacciHeapNode Next;
9 |
10 | internal FibonacciHeapNode Previous;
11 |
12 | internal FibonacciHeapNode(T value)
13 | {
14 | Value = value;
15 | }
16 |
17 | internal T Value { get; set; }
18 | internal FibonacciHeapNode ChildrenHead { get; set; }
19 |
20 | internal FibonacciHeapNode Parent { get; set; }
21 | internal bool LostChild { get; set; }
22 |
23 | public int CompareTo(object obj)
24 | {
25 | return Value.CompareTo(((FibonacciHeapNode)obj).Value);
26 | }
27 | }
--------------------------------------------------------------------------------
/src/Advanced.Algorithms/DataStructures/Heap/Shared/PairingHeapNode.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace Advanced.Algorithms.DataStructures;
4 |
5 | internal class PairingHeapNode : IComparable where T : IComparable
6 | {
7 | internal PairingHeapNode Next;
8 |
9 | internal PairingHeapNode Previous;
10 |
11 | internal PairingHeapNode(T value)
12 | {
13 | Value = value;
14 | }
15 |
16 | internal T Value { get; set; }
17 |
18 | internal PairingHeapNode ChildrenHead { get; set; }
19 | internal bool IsHeadChild => Previous != null && Previous.ChildrenHead == this;
20 |
21 | public int CompareTo(object obj)
22 | {
23 | return Value.CompareTo(((PairingHeapNode)obj).Value);
24 | }
25 | }
--------------------------------------------------------------------------------
/src/Advanced.Algorithms/DataStructures/Queues/ArrayQueue.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections;
3 | using System.Collections.Generic;
4 |
5 | namespace Advanced.Algorithms.DataStructures.Foundation;
6 |
7 | internal class ArrayQueue : IQueue
8 | {
9 | private readonly List list = new();
10 |
11 | public int Count { get; private set; }
12 |
13 | public void Enqueue(T item)
14 | {
15 | list.Insert(0, item);
16 | Count++;
17 | }
18 |
19 | public T Dequeue()
20 | {
21 | if (list.Count == 0) throw new Exception("Empty Queue");
22 |
23 | var result = list[list.Count - 1];
24 | list.RemoveAt(list.Count - 1);
25 | Count--;
26 | return result;
27 | }
28 |
29 | public IEnumerator GetEnumerator()
30 | {
31 | return GetEnumerator();
32 | }
33 |
34 | IEnumerator IEnumerable.GetEnumerator()
35 | {
36 | return list.GetEnumerator();
37 | }
38 | }
--------------------------------------------------------------------------------
/src/Advanced.Algorithms/DataStructures/Queues/LinkedListQueue.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections;
3 | using System.Collections.Generic;
4 |
5 | namespace Advanced.Algorithms.DataStructures.Foundation;
6 |
7 | internal class LinkedListQueue : IQueue
8 | {
9 | private readonly DoublyLinkedList list = new();
10 |
11 | public int Count { get; private set; }
12 |
13 | public void Enqueue(T item)
14 | {
15 | list.InsertFirst(item);
16 | Count++;
17 | }
18 |
19 | public T Dequeue()
20 | {
21 | if (list.Head == null) throw new Exception("Empty Queue");
22 |
23 | var result = list.DeleteLast();
24 | Count--;
25 | return result;
26 | }
27 |
28 | public IEnumerator GetEnumerator()
29 | {
30 | return GetEnumerator();
31 | }
32 |
33 | IEnumerator IEnumerable.GetEnumerator()
34 | {
35 | return list.GetEnumerator();
36 | }
37 | }
--------------------------------------------------------------------------------
/src/Advanced.Algorithms/DataStructures/Queues/PriorityQueue.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections;
3 | using System.Collections.Generic;
4 |
5 | namespace Advanced.Algorithms.DataStructures;
6 |
7 | ///
8 | /// A priority queue implementation using heap
9 | ///
10 | public class PriorityQueue : IEnumerable where T : IComparable
11 | {
12 | private readonly BHeap heap;
13 |
14 | public PriorityQueue(SortDirection sortDirection = SortDirection.Ascending)
15 | {
16 | heap = new BHeap(sortDirection);
17 | }
18 |
19 | public IEnumerator GetEnumerator()
20 | {
21 | return GetEnumerator();
22 | }
23 |
24 | IEnumerator IEnumerable.GetEnumerator()
25 | {
26 | return heap.GetEnumerator();
27 | }
28 |
29 | ///
30 | /// Time complexity:O(log(n)).
31 | ///
32 | public void Enqueue(T item)
33 | {
34 | heap.Insert(item);
35 | }
36 |
37 | ///
38 | /// Time complexity:O(log(n)).
39 | ///
40 | public T Dequeue()
41 | {
42 | return heap.Extract();
43 | }
44 |
45 | ///
46 | /// Time complexity:O(1).
47 | ///
48 | public T Peek()
49 | {
50 | return heap.Peek();
51 | }
52 | }
--------------------------------------------------------------------------------
/src/Advanced.Algorithms/DataStructures/Queues/Queue.cs:
--------------------------------------------------------------------------------
1 | using System.Collections;
2 | using System.Collections.Generic;
3 |
4 | namespace Advanced.Algorithms.DataStructures.Foundation;
5 |
6 | ///
7 | /// A queue implementation.
8 | ///
9 | public class Queue : IEnumerable
10 | {
11 | private readonly IQueue queue;
12 |
13 | /// The queue implementation type.
14 | public Queue(QueueType type = QueueType.Array)
15 | {
16 | if (type == QueueType.Array)
17 | queue = new ArrayQueue();
18 | else
19 | queue = new LinkedListQueue();
20 | }
21 |
22 | ///
23 | /// The number of items in the queue.
24 | ///
25 | public int Count => queue.Count;
26 |
27 | public IEnumerator GetEnumerator()
28 | {
29 | return GetEnumerator();
30 | }
31 |
32 | IEnumerator IEnumerable.GetEnumerator()
33 | {
34 | return queue.GetEnumerator();
35 | }
36 |
37 | ///
38 | /// Time complexity:O(1).
39 | ///
40 | public void Enqueue(T item)
41 | {
42 | queue.Enqueue(item);
43 | }
44 |
45 | ///
46 | /// Time complexity:O(1).
47 | ///
48 | public T Dequeue()
49 | {
50 | return queue.Dequeue();
51 | }
52 | }
53 |
54 | internal interface IQueue : IEnumerable
55 | {
56 | int Count { get; }
57 | void Enqueue(T item);
58 | T Dequeue();
59 | }
60 |
61 | ///
62 | /// The queue implementation types.
63 | ///
64 | public enum QueueType
65 | {
66 | Array = 0,
67 | LinkedList = 1
68 | }
--------------------------------------------------------------------------------
/src/Advanced.Algorithms/DataStructures/Set/BloomFilter.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections;
3 | using System.Collections.Generic;
4 |
5 | namespace Advanced.Algorithms.DataStructures;
6 |
7 | ///
8 | /// A simple bloom filter implementation.
9 | ///
10 | public class BloomFilter
11 | {
12 | private readonly BitArray filter;
13 |
14 | private readonly int numberOfHashFunctions;
15 |
16 | ///
17 | /// Higher the size lower the collision and
18 | /// failure probablity.
19 | ///
20 | public BloomFilter(int size, int numberOfHashFunctions = 2)
21 | {
22 | if (size <= numberOfHashFunctions)
23 | throw new ArgumentException("size cannot be less than or equal to numberOfHashFunctions.");
24 |
25 | this.numberOfHashFunctions = numberOfHashFunctions;
26 | filter = new BitArray(size);
27 | }
28 |
29 | ///
30 | /// Time complexity: O(1).
31 | ///
32 | public void AddKey(T key)
33 | {
34 | foreach (var hash in GetHashes(key)) filter[hash % filter.Length] = true;
35 | }
36 |
37 | ///
38 | /// Time complexity: O(1).
39 | ///
40 | public bool KeyExists(T key)
41 | {
42 | foreach (var hash in GetHashes(key))
43 | if (filter[hash % filter.Length] == false)
44 | return false;
45 |
46 | return true;
47 | }
48 |
49 | private IEnumerable GetHashes(T key)
50 | {
51 | for (var i = 1; i <= numberOfHashFunctions; i++)
52 | {
53 | var obj = new { Key = key, InitialValue = i };
54 | yield return Math.Abs(obj.GetHashCode());
55 | }
56 | }
57 | }
--------------------------------------------------------------------------------
/src/Advanced.Algorithms/DataStructures/Shared/IEnumerableExtensions.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 |
3 | namespace Advanced.Algorithms.DataStructures;
4 |
5 | internal static class EnumerableExtensions
6 | {
7 | internal static IEnumerable AsEnumerable(this IEnumerator e)
8 | {
9 | while (e.MoveNext()) yield return e.Current;
10 | }
11 | }
--------------------------------------------------------------------------------
/src/Advanced.Algorithms/DataStructures/Stack/ArrayStack.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections;
3 | using System.Collections.Generic;
4 |
5 | namespace Advanced.Algorithms.DataStructures.Foundation;
6 |
7 | internal class ArrayStack : IStack
8 | {
9 | private readonly List list = new();
10 | public int Count { get; private set; }
11 |
12 | public T Pop()
13 | {
14 | if (Count == 0) throw new Exception("Empty stack");
15 |
16 | var result = list[list.Count - 1];
17 | list.RemoveAt(list.Count - 1);
18 | Count--;
19 | return result;
20 | }
21 |
22 | public void Push(T item)
23 | {
24 | list.Add(item);
25 | Count++;
26 | }
27 |
28 | public T Peek()
29 | {
30 | if (Count == 0) return default;
31 |
32 | return list[list.Count - 1];
33 | }
34 |
35 | public IEnumerator GetEnumerator()
36 | {
37 | return GetEnumerator();
38 | }
39 |
40 | IEnumerator IEnumerable.GetEnumerator()
41 | {
42 | return list.GetEnumerator();
43 | }
44 | }
--------------------------------------------------------------------------------
/src/Advanced.Algorithms/DataStructures/Stack/LinkedListStack.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections;
3 | using System.Collections.Generic;
4 |
5 | namespace Advanced.Algorithms.DataStructures.Foundation;
6 |
7 | internal class LinkedListStack : IStack
8 | {
9 | private readonly SinglyLinkedList list = new();
10 | public int Count { get; private set; }
11 |
12 | public T Pop()
13 | {
14 | if (Count == 0) throw new Exception("Empty stack");
15 |
16 | var result = list.DeleteFirst();
17 | Count--;
18 | return result;
19 | }
20 |
21 | public void Push(T item)
22 | {
23 | list.InsertFirst(item);
24 | Count++;
25 | }
26 |
27 | public T Peek()
28 | {
29 | return Count == 0 ? default : list.Head.Data;
30 | }
31 |
32 | public IEnumerator GetEnumerator()
33 | {
34 | return GetEnumerator();
35 | }
36 |
37 | IEnumerator IEnumerable.GetEnumerator()
38 | {
39 | return list.GetEnumerator();
40 | }
41 | }
--------------------------------------------------------------------------------
/src/Advanced.Algorithms/DataStructures/Stack/Stack.cs:
--------------------------------------------------------------------------------
1 | using System.Collections;
2 | using System.Collections.Generic;
3 |
4 | namespace Advanced.Algorithms.DataStructures.Foundation;
5 |
6 | ///
7 | /// A stack implementation.
8 | ///
9 | public class Stack : IEnumerable
10 | {
11 | private readonly IStack stack;
12 |
13 | /// The stack type to use.
14 | public Stack(StackType type = StackType.Array)
15 | {
16 | if (type == StackType.Array)
17 | stack = new ArrayStack();
18 | else
19 | stack = new LinkedListStack();
20 | }
21 |
22 | ///
23 | /// The total number of items in this stack.
24 | ///
25 | public int Count => stack.Count;
26 |
27 | public IEnumerator GetEnumerator()
28 | {
29 | return GetEnumerator();
30 | }
31 |
32 | IEnumerator IEnumerable.GetEnumerator()
33 | {
34 | return stack.GetEnumerator();
35 | }
36 |
37 | ///
38 | /// Time complexity:O(1).
39 | ///
40 | /// The item popped.
41 | public T Pop()
42 | {
43 | return stack.Pop();
44 | }
45 |
46 | ///
47 | /// Time complexity:O(1).
48 | ///
49 | /// The item to push.
50 | public void Push(T item)
51 | {
52 | stack.Push(item);
53 | }
54 |
55 | ///
56 | /// Peek from stack.
57 | /// Time complexity:O(1).
58 | ///
59 | /// The item peeked.
60 | public T Peek()
61 | {
62 | return stack.Peek();
63 | }
64 | }
65 |
66 | internal interface IStack : IEnumerable
67 | {
68 | int Count { get; }
69 | T Pop();
70 | void Push(T item);
71 |
72 | T Peek();
73 | }
74 |
75 | ///
76 | /// The stack implementation types.
77 | ///
78 | public enum StackType
79 | {
80 | Array = 0,
81 | LinkedList = 1
82 | }
--------------------------------------------------------------------------------
/src/Advanced.Algorithms/DataStructures/Tree/Shared/ArrayComparer.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 |
3 | namespace Advanced.Algorithms.DataStructures;
4 |
5 | ///
6 | /// Compares two arrays.
7 | ///
8 | internal class ArrayComparer : IEqualityComparer
9 | {
10 | public bool Equals(T[] x, T[] y)
11 | {
12 | if (x == y) return true;
13 |
14 | for (var i = 0; i < x.Length; i++)
15 | if (!x[i].Equals(y[i]))
16 | return false;
17 |
18 | return true;
19 | }
20 |
21 | public int GetHashCode(T[] x)
22 | {
23 | unchecked
24 | {
25 | if (x == null) return 0;
26 |
27 | var hash = 17;
28 |
29 | foreach (var element in x) hash = hash * 31 + element.GetHashCode();
30 |
31 | return hash;
32 | }
33 | }
34 | }
--------------------------------------------------------------------------------
/src/Advanced.Algorithms/DataStructures/Tree/Shared/BSTEnumerator.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections;
3 | using System.Collections.Generic;
4 |
5 | namespace Advanced.Algorithms.DataStructures;
6 |
7 | // implement IEnumerator.
8 | internal class BstEnumerator : IEnumerator where T : IComparable
9 | {
10 | private readonly bool asc;
11 |
12 | private readonly BstNodeBase root;
13 | private BstNodeBase current;
14 |
15 | internal BstEnumerator(BstNodeBase root, bool asc = true)
16 | {
17 | this.root = root;
18 | this.asc = asc;
19 | }
20 |
21 | public bool MoveNext()
22 | {
23 | if (root == null) return false;
24 |
25 | if (current == null)
26 | {
27 | current = asc ? root.FindMin() : root.FindMax();
28 | return true;
29 | }
30 |
31 | var next = asc ? current.NextHigher() : current.NextLower();
32 | if (next != null)
33 | {
34 | current = next;
35 | return true;
36 | }
37 |
38 | return false;
39 | }
40 |
41 | public void Reset()
42 | {
43 | current = root;
44 | }
45 |
46 | public T Current => current.Value;
47 |
48 | object IEnumerator.Current => Current;
49 |
50 | public void Dispose()
51 | {
52 | current = null;
53 | }
54 | }
--------------------------------------------------------------------------------
/src/Advanced.Algorithms/DataStructures/Tree/Shared/BSTHelpers.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 |
4 | namespace Advanced.Algorithms.DataStructures;
5 |
6 | internal class BstHelpers
7 | {
8 | internal static void ValidateSortedCollection(IEnumerable sortedCollection) where T : IComparable
9 | {
10 | if (!IsSorted(sortedCollection))
11 | throw new ArgumentException("Initial collection should have unique keys and be in sorted order.");
12 | }
13 |
14 | internal static BstNodeBase ToBst(BstNodeBase[] sortedNodes) where T : IComparable
15 | {
16 | return ToBst(sortedNodes, 0, sortedNodes.Length - 1);
17 | }
18 |
19 | internal static int AssignCount(BstNodeBase node) where T : IComparable
20 | {
21 | if (node == null) return 0;
22 |
23 | node.Count = AssignCount(node.Left) + AssignCount(node.Right) + 1;
24 |
25 | return node.Count;
26 | }
27 |
28 | private static BstNodeBase ToBst(BstNodeBase[] sortedNodes, int start, int end) where T : IComparable
29 | {
30 | if (start > end)
31 | return null;
32 |
33 | var mid = (start + end) / 2;
34 | var root = sortedNodes[mid];
35 |
36 | root.Left = ToBst(sortedNodes, start, mid - 1);
37 | if (root.Left != null) root.Left.Parent = root;
38 |
39 | root.Right = ToBst(sortedNodes, mid + 1, end);
40 | if (root.Right != null) root.Right.Parent = root;
41 |
42 | return root;
43 | }
44 |
45 | private static bool IsSorted(IEnumerable collection) where T : IComparable
46 | {
47 | var enumerator = collection.GetEnumerator();
48 | if (!enumerator.MoveNext()) return true;
49 |
50 | var previous = enumerator.Current;
51 |
52 | while (enumerator.MoveNext())
53 | {
54 | var current = enumerator.Current;
55 |
56 | if (current.CompareTo(previous) <= 0) return false;
57 | }
58 |
59 | return true;
60 | }
61 | }
--------------------------------------------------------------------------------
/src/Advanced.Algorithms/DataStructures/Tree/Shared/BSTNodeBase.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace Advanced.Algorithms.DataStructures;
4 |
5 | internal abstract class BstNodeBase where T : IComparable
6 | {
7 | //Count of nodes under this node including this node.
8 | //Used to fasten kth smallest computation.
9 | internal int Count { get; set; } = 1;
10 |
11 | internal virtual BstNodeBase Parent { get; set; }
12 |
13 | internal virtual BstNodeBase Left { get; set; }
14 | internal virtual BstNodeBase Right { get; set; }
15 |
16 | internal T Value { get; set; }
17 |
18 | internal bool IsLeftChild => Parent.Left == this;
19 | internal bool IsRightChild => Parent.Right == this;
20 |
21 | internal bool IsLeaf => Left == null && Right == null;
22 | }
--------------------------------------------------------------------------------
/src/Advanced.Algorithms/Distributed/AsyncQueue.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using System.Threading;
3 | using System.Threading.Tasks;
4 |
5 | namespace Advanced.Algorithms.Distributed;
6 |
7 | ///
8 | /// A simple asynchronous multi-thread supporting producer/consumer FIFO queue with minimal locking.
9 | ///
10 | public class AsyncQueue
11 | {
12 | //consumer task queue and lock.
13 | private readonly Queue> consumerQueue = new();
14 |
15 | //data queue.
16 | private readonly Queue queue = new();
17 | private readonly SemaphoreSlim consumerQueueLock = new(1);
18 |
19 | public int Count => queue.Count;
20 |
21 | ///
22 | /// Supports multi-threaded producers.
23 | /// Time complexity: O(1).
24 | ///
25 | public async Task EnqueueAsync(T value, int millisecondsTimeout = int.MaxValue,
26 | CancellationToken taskCancellationToken = default)
27 | {
28 | await consumerQueueLock.WaitAsync(millisecondsTimeout, taskCancellationToken);
29 |
30 | if (consumerQueue.Count > 0)
31 | {
32 | var consumer = consumerQueue.Dequeue();
33 | consumer.TrySetResult(value);
34 | }
35 | else
36 | {
37 | queue.Enqueue(value);
38 | }
39 |
40 | consumerQueueLock.Release();
41 | }
42 |
43 | ///
44 | /// Supports multi-threaded consumers.
45 | /// Time complexity: O(1).
46 | ///
47 | public async Task DequeueAsync(int millisecondsTimeout = int.MaxValue,
48 | CancellationToken taskCancellationToken = default)
49 | {
50 | await consumerQueueLock.WaitAsync(millisecondsTimeout, taskCancellationToken);
51 |
52 | TaskCompletionSource consumer;
53 |
54 | try
55 | {
56 | if (queue.Count > 0)
57 | {
58 | var result = queue.Dequeue();
59 | return result;
60 | }
61 |
62 | consumer = new TaskCompletionSource();
63 | taskCancellationToken.Register(() => consumer.TrySetCanceled());
64 | consumerQueue.Enqueue(consumer);
65 | }
66 | finally
67 | {
68 | consumerQueueLock.Release();
69 | }
70 |
71 | return await consumer.Task;
72 | }
73 | }
--------------------------------------------------------------------------------
/src/Advanced.Algorithms/Distributed/LRUCache.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using Advanced.Algorithms.DataStructures;
5 |
6 | namespace Advanced.Algorithms.Distributed;
7 |
8 | ///
9 | /// A least recently used cache implemetation.
10 | ///
11 | public class LruCache
12 | {
13 | private readonly int capacity;
14 |
15 | private readonly DoublyLinkedList> dll = new();
16 |
17 | private readonly Dictionary>> lookUp = new();
18 |
19 | public LruCache(int capacity)
20 | {
21 | if (capacity <= 0) throw new Exception("Capacity must be a positive integer.");
22 | this.capacity = capacity;
23 | }
24 |
25 | ///
26 | /// Time complexity: O(1).
27 | ///
28 | public TV Get(TK key)
29 | {
30 | if (!lookUp.ContainsKey(key))
31 | return default;
32 |
33 | var node = lookUp[key];
34 |
35 | //move lately used node to beginning of ddl
36 | dll.Delete(node);
37 | var newNode = dll.InsertFirst(node.Data);
38 | lookUp[key] = newNode;
39 |
40 | return node.Data.Item2;
41 | }
42 |
43 | ///
44 | /// Time complexity: O(1).
45 | ///
46 | public void Put(TK key, TV value)
47 | {
48 | //evict last node of ddl if capacity overflows
49 | if (lookUp.Count == capacity)
50 | {
51 | var nodeToEvict = dll.Last();
52 | lookUp.Remove(nodeToEvict.Item1);
53 | dll.DeleteLast();
54 | }
55 |
56 | //insert
57 | var newNode = dll.InsertFirst(new Tuple(key, value));
58 | lookUp.Add(key, newNode);
59 | }
60 | }
--------------------------------------------------------------------------------
/src/Advanced.Algorithms/Geometry/ClosestPointPair.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 |
5 | namespace Advanced.Algorithms.Geometry;
6 |
7 | ///
8 | /// Closest-point pair finder.
9 | ///
10 | public class ClosestPointPair
11 | {
12 | public static double Find(List points)
13 | {
14 | var xSorted = points
15 | .Select(z => new Point(z[0], z[1]))
16 | .OrderBy(p => p.X).ToList();
17 |
18 | return Find(xSorted, 0, points.Count - 1);
19 | }
20 |
21 | public static double Find(List points, int left, int right)
22 | {
23 | if (right - left <= 3) return BruteForce(points, left, right);
24 |
25 | var mid = (left + right) / 2;
26 |
27 | var leftMin = Find(points, 0, mid);
28 | var rightMin = Find(points, mid + 1, right);
29 |
30 | var min = Math.Min(leftMin, rightMin);
31 | var midX = points[mid].X;
32 |
33 | var strips = new List();
34 |
35 | for (var i = left; i <= right; i++)
36 | if (Math.Abs(points[i].X - midX) < min)
37 | strips.Add(points[i]);
38 |
39 | //vertical strips within the radius of min
40 | strips = strips.OrderBy(p => p.Y).ToList();
41 |
42 | for (var i = 0; i < strips.Count; i++)
43 | for (var j = i + 1; j < strips.Count && Math.Abs(strips[i].Y - strips[j].Y) < min; j++)
44 | //check for radius
45 | min = Math.Min(min, GetDistance(strips[i], strips[j]));
46 |
47 | return min;
48 | }
49 |
50 | private static double BruteForce(IList points, int left, int right)
51 | {
52 | var min = double.MaxValue;
53 | for (var i = left; i < right; i++)
54 | for (var j = left + 1; j <= right; j++)
55 | min = Math.Min(min, GetDistance(points[i], points[j]));
56 | return min;
57 | }
58 |
59 | ///
60 | /// Eucledian distance.
61 | ///
62 | private static double GetDistance(Point point1, Point point2)
63 | {
64 | return Math.Sqrt(Math.Pow(Math.Abs(point1.X - point2.X), 2)
65 | + Math.Pow(Math.Abs(point1.Y - point2.Y), 2));
66 | }
67 | }
--------------------------------------------------------------------------------
/src/Advanced.Algorithms/Geometry/ConvexHull.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 |
3 | namespace Advanced.Algorithms.Geometry;
4 |
5 | ///
6 | /// Convex hull using jarvis's algorithm.
7 | ///
8 | public class ConvexHull
9 | {
10 | public static List Find(List points)
11 | {
12 | var currentPointIndex = FindLeftMostPoint(points);
13 | var startingPointIndex = currentPointIndex;
14 |
15 | var result = new List();
16 |
17 | do
18 | {
19 | result.Add(points[currentPointIndex]);
20 |
21 | //pick a random point as next Point
22 | var nextPointIndex = (currentPointIndex + 1) % points.Count;
23 |
24 | for (var i = 0; i < points.Count; i++)
25 | {
26 | if (i == nextPointIndex) continue;
27 |
28 | var orientation = GetOrientation(points[currentPointIndex],
29 | points[i], points[nextPointIndex]);
30 |
31 | if (orientation == Orientation.ClockWise) nextPointIndex = i;
32 | }
33 |
34 | currentPointIndex = nextPointIndex;
35 | } while (currentPointIndex != startingPointIndex);
36 |
37 | return result;
38 | }
39 |
40 | ///
41 | /// Compute the orientation of the lines formed by points p, q and r
42 | ///
43 | private static Orientation GetOrientation(int[] p, int[] q, int[] r)
44 | {
45 | int x1 = p[0], y1 = p[1];
46 | int x2 = q[0], y2 = q[1];
47 | int x3 = r[0], y3 = r[1];
48 |
49 | //using slope formula => (y2-y1)/(x2-x1) = (y3-y2)/(x3-x2) (if colinear)
50 | // derives to (y2-y1)(x3-x2)-(y3-y2)(x2-x1) == 0
51 | var result = (y2 - y1) * (x3 - x2) - (y3 - y2) * (x2 - x1);
52 |
53 | //sign will give the direction
54 | if (result < 0) return Orientation.ClockWise;
55 |
56 | return result > 0 ? Orientation.AntiClockWise : Orientation.Colinear;
57 | }
58 |
59 |
60 | private static int FindLeftMostPoint(List points)
61 | {
62 | var left = 0;
63 |
64 | for (var i = 1; i < points.Count; i++)
65 | if (points[i][0] < points[left][0])
66 | left = i;
67 |
68 | return left;
69 | }
70 |
71 | private enum Orientation
72 | {
73 | ClockWise = 0,
74 | AntiClockWise = 1,
75 | Colinear = 2
76 | }
77 | }
--------------------------------------------------------------------------------
/src/Advanced.Algorithms/Geometry/PointInsidePolygon.cs:
--------------------------------------------------------------------------------
1 | namespace Advanced.Algorithms.Geometry;
2 |
3 | ///
4 | /// Check whether a given point is inside given polygon.
5 | ///
6 | public class PointInsidePolygon
7 | {
8 | public static bool IsInside(Polygon polygon, Point point)
9 | {
10 | //a imaginary ray line from point to right infinity
11 | var rayLine = new Line(point, new Point(double.MaxValue, point.Y));
12 |
13 | var intersectionCount = 0;
14 | for (var i = 0; i < polygon.Edges.Count - 1; i++)
15 | {
16 | var edgeLine = polygon.Edges[i];
17 |
18 | if (LineIntersection.Find(rayLine, edgeLine) != null) intersectionCount++;
19 | }
20 |
21 | //should have odd intersections if point is inside the polygon
22 | return intersectionCount % 2 != 0;
23 | }
24 | }
--------------------------------------------------------------------------------
/src/Advanced.Algorithms/Geometry/PointRotation.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace Advanced.Algorithms.Geometry;
4 |
5 | ///
6 | /// Rotates given point by given angle about given center.
7 | ///
8 | public class PointRotation
9 | {
10 | public static Point Rotate(Point center, Point point, int angle)
11 | {
12 | var angleInRadians = angle * (Math.PI / 180);
13 |
14 | var cosTheta = Math.Cos(angleInRadians);
15 | var sinTheta = Math.Sin(angleInRadians);
16 |
17 | var x = cosTheta * (point.X - center.X) -
18 | sinTheta * (point.Y - center.Y) + center.X;
19 |
20 | var y = sinTheta * (point.X - center.X) +
21 | cosTheta * (point.Y - center.Y) + center.Y;
22 |
23 | return new Point(x, y);
24 | }
25 | }
--------------------------------------------------------------------------------
/src/Advanced.Algorithms/Geometry/RectangleIntersection.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace Advanced.Algorithms.Geometry;
4 |
5 | ///
6 | /// Rectangle intersection finder.
7 | ///
8 | public class RectangleIntersection
9 | {
10 | ///
11 | /// Returns the rectangle formed by the intersection if do intersect.
12 | /// Otherwise default value of Rectangle struct.
13 | ///
14 | public static Rectangle FindIntersection(Rectangle a, Rectangle b)
15 | {
16 | //check for intersection
17 | if (!DoIntersect(a, b))
18 | //no intersection
19 | return null;
20 |
21 | var leftTopCorner = new Point
22 | (
23 | Math.Max(a.LeftTop.X, b.LeftTop.X),
24 | Math.Min(a.LeftTop.Y, b.LeftTop.Y)
25 | );
26 |
27 |
28 | var rightBottomCorner = new Point
29 | (
30 | Math.Min(a.RightBottom.X, b.RightBottom.X),
31 | Math.Max(a.RightBottom.Y, b.RightBottom.Y)
32 | );
33 |
34 |
35 | return new Rectangle
36 | {
37 | LeftTop = leftTopCorner,
38 | RightBottom = rightBottomCorner
39 | };
40 | }
41 |
42 | public static bool DoIntersect(Rectangle a, Rectangle b)
43 | {
44 | //check for intersection
45 | if (a.LeftTop.X > b.RightBottom.X // A is right of B
46 | || a.RightBottom.X < b.LeftTop.X // A is left of B
47 | || a.RightBottom.Y > b.LeftTop.Y //A is above B
48 | || a.LeftTop.Y < b.RightBottom.Y) //A is below B
49 | //no intersection
50 | return false;
51 |
52 | return true;
53 | }
54 | }
--------------------------------------------------------------------------------
/src/Advanced.Algorithms/Geometry/Shapes/Line.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace Advanced.Algorithms.Geometry;
4 |
5 | ///
6 | /// Line object.
7 | ///
8 | public class Line
9 | {
10 | private readonly Lazy slope;
11 |
12 | private Line()
13 | {
14 | slope = new Lazy(() => CalcSlope());
15 | }
16 |
17 | internal Line(Point start, Point end, double tolerance)
18 | : this()
19 | {
20 | if (start.X < end.X)
21 | {
22 | Left = start;
23 | Right = end;
24 | }
25 | else if (start.X > end.X)
26 | {
27 | Left = end;
28 | Right = start;
29 | }
30 | else
31 | {
32 | //use Y
33 | if (start.Y < end.Y)
34 | {
35 | Left = start;
36 | Right = end;
37 | }
38 | else
39 | {
40 | Left = end;
41 | Right = start;
42 | }
43 | }
44 | }
45 |
46 | public Line(Point start, Point end, int precision = 5)
47 | : this(start, end, Math.Round(Math.Pow(0.1, precision), precision))
48 | {
49 | }
50 |
51 | public Point Left { get; }
52 | public Point Right { get; }
53 |
54 | public bool IsVertical => Left.X == Right.X;
55 | public bool IsHorizontal => Left.Y == Right.Y;
56 |
57 | public double Slope => slope.Value;
58 |
59 | private double CalcSlope()
60 | {
61 | Point left = Left, right = Right;
62 |
63 | //vertical line has infinite slope
64 | if (left.Y == right.Y) return double.MaxValue;
65 |
66 | return (right.Y - left.Y) / (right.X - left.X);
67 | }
68 |
69 | public Line Clone()
70 | {
71 | return new Line(Left.Clone(), Right.Clone());
72 | }
73 | }
--------------------------------------------------------------------------------
/src/Advanced.Algorithms/Geometry/Shapes/Point.cs:
--------------------------------------------------------------------------------
1 | namespace Advanced.Algorithms.Geometry;
2 |
3 | ///
4 | /// Point object.
5 | ///
6 | public class Point
7 | {
8 | public Point(double x, double y)
9 | {
10 | X = x;
11 | Y = y;
12 | }
13 |
14 | public double X { get; }
15 | public double Y { get; }
16 |
17 | public override string ToString()
18 | {
19 | return X.ToString("F") + " " + Y.ToString("F");
20 | }
21 |
22 | public Point Clone()
23 | {
24 | return new Point(X, Y);
25 | }
26 | }
--------------------------------------------------------------------------------
/src/Advanced.Algorithms/Geometry/Shapes/Polygon.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 |
3 | namespace Advanced.Algorithms.Geometry;
4 |
5 | ///
6 | /// Polygon object.
7 | ///
8 | public class Polygon
9 | {
10 | ///
11 | /// Create a polygon with given edges lines.
12 | ///
13 | public Polygon(List edges)
14 | {
15 | Edges = edges;
16 | }
17 |
18 | ///
19 | /// Create polygon from the given list of consecutive boundary end points.
20 | /// Last and first points will be connected.
21 | /// If only one edge point is provided then this polygon will behave like a point,
22 | /// a line is created with both ends having same edge point.
23 | ///
24 | public Polygon(List edgePoints)
25 | {
26 | Edges = new List();
27 |
28 | for (var i = 0; i < edgePoints.Count; i++)
29 | Edges.Add(new Line(edgePoints[i], edgePoints[(i + 1) % edgePoints.Count]));
30 | }
31 |
32 | public List Edges { get; set; }
33 | }
--------------------------------------------------------------------------------
/src/Advanced.Algorithms/Geometry/Shapes/Rectangle.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 |
4 | namespace Advanced.Algorithms.Geometry;
5 |
6 | ///
7 | /// Rectangle object.
8 | ///
9 | public class Rectangle
10 | {
11 | public Rectangle()
12 | {
13 | }
14 |
15 | public Rectangle(Point leftTop, Point rightBottom)
16 | {
17 | if (rightBottom.Y > leftTop.Y) throw new Exception("Top corner should have higher Y value than bottom.");
18 |
19 | if (leftTop.X > rightBottom.X) throw new Exception("Right corner should have higher X value than left.");
20 |
21 | LeftTop = leftTop;
22 | RightBottom = rightBottom;
23 | }
24 |
25 | public Point LeftTop { get; set; }
26 | public Point RightBottom { get; set; }
27 |
28 | internal double Length => Math.Abs(RightBottom.X - LeftTop.X);
29 | internal double Breadth => Math.Abs(LeftTop.Y - RightBottom.Y);
30 |
31 | internal double Area()
32 | {
33 | return Length * Breadth;
34 | }
35 |
36 | public Polygon ToPolygon()
37 | {
38 | var edges = new List();
39 |
40 | //add all four edge lines of this rectangle
41 | edges.Add(new Line(LeftTop, new Point(RightBottom.X, LeftTop.Y)));
42 | edges.Add(new Line(new Point(RightBottom.X, LeftTop.Y), RightBottom));
43 | edges.Add(new Line(RightBottom, new Point(LeftTop.X, RightBottom.Y)));
44 | edges.Add(new Line(new Point(LeftTop.X, RightBottom.Y), LeftTop));
45 |
46 | return new Polygon(edges);
47 | }
48 | }
--------------------------------------------------------------------------------
/src/Advanced.Algorithms/Geometry/Shared/DoubleExtensions.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace Advanced.Algorithms.Geometry;
4 |
5 | internal static class DoubleExtensions
6 | {
7 | internal static bool IsLessThan(this double a, double b, double tolerance)
8 | {
9 | return a - b < -tolerance;
10 | }
11 |
12 | internal static bool IsLessThanOrEqual(this double a, double b, double tolerance)
13 | {
14 | var result = a - b;
15 |
16 | return result < -tolerance || Math.Abs(result) < tolerance;
17 | }
18 |
19 | internal static bool IsGreaterThan(this double a, double b, double tolerance)
20 | {
21 | return a - b > tolerance;
22 | }
23 |
24 | internal static bool IsGreaterThanOrEqual(this double a, double b, double tolerance)
25 | {
26 | var result = a - b;
27 | return result > tolerance || Math.Abs(result) < tolerance;
28 | }
29 | }
--------------------------------------------------------------------------------
/src/Advanced.Algorithms/Geometry/Shared/PointComparer.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 |
3 | namespace Advanced.Algorithms.Geometry;
4 |
5 | ///
6 | /// Compares two points for geometric equality implementing IEqualityComparer.
7 | ///
8 | public class PointComparer : IEqualityComparer
9 | {
10 | public bool Equals(Point x, Point y)
11 | {
12 | if (x == null && y == null) return true;
13 |
14 | // Check for null values
15 | if (x == null || y == null) return false;
16 |
17 | if (x == y) return true;
18 |
19 | return x.X == y.X && x.Y == y.Y;
20 | }
21 |
22 | public int GetHashCode(Point point)
23 | {
24 | var hashCode = 33;
25 | hashCode = hashCode * -21 + point.X.GetHashCode();
26 | hashCode = hashCode * -21 + point.Y.GetHashCode();
27 | return hashCode;
28 | }
29 | }
--------------------------------------------------------------------------------
/src/Advanced.Algorithms/Geometry/Shared/RectangleComparer.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 |
3 | namespace Advanced.Algorithms.Geometry;
4 |
5 | ///
6 | /// Compares two rectangles for geometrical equality implementing IEqualityComparer.
7 | ///
8 | public class RectangleComparer : IEqualityComparer
9 | {
10 | public bool Equals(Rectangle x, Rectangle y)
11 | {
12 | if (x == null && y == null) return true;
13 |
14 | // Check for null values
15 | if (x == null || y == null) return false;
16 |
17 | return x.LeftTop.X == y.LeftTop.X
18 | && x.LeftTop.Y == y.LeftTop.Y
19 | && x.RightBottom.X == y.RightBottom.X
20 | && x.RightBottom.Y == y.RightBottom.Y;
21 | }
22 |
23 | public int GetHashCode(Rectangle rectangle)
24 | {
25 | var hashCode = 35;
26 | hashCode = hashCode * -26 + rectangle.LeftTop.GetHashCode();
27 | hashCode = hashCode * -26 + rectangle.RightBottom.GetHashCode();
28 | return hashCode;
29 | }
30 | }
--------------------------------------------------------------------------------
/src/Advanced.Algorithms/Graph/Connectivity/TarjansBiConnected.cs:
--------------------------------------------------------------------------------
1 | using Advanced.Algorithms.DataStructures.Graph;
2 |
3 | namespace Advanced.Algorithms.Graph;
4 |
5 | ///
6 | /// Finds if a graph is BiConnected.
7 | ///
8 | public class TarjansBiConnected
9 | {
10 | ///
11 | /// This is using ariticulation alogrithm based on the observation that
12 | /// a graph is BiConnected if and only if there is no articulation Points.
13 | ///
14 | public bool IsBiConnected(IGraph graph)
15 | {
16 | var algorithm = new TarjansArticulationFinder();
17 | return algorithm.FindArticulationPoints(graph).Count == 0;
18 | }
19 | }
--------------------------------------------------------------------------------
/src/Advanced.Algorithms/Graph/Cover/MinVertexCover.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using Advanced.Algorithms.DataStructures.Graph;
3 |
4 | namespace Advanced.Algorithms.Graph;
5 |
6 | ///
7 | /// A minimum vertex conver algorithm implementation.
8 | ///
9 | public class MinVertexCover
10 | {
11 | public List> GetMinVertexCover(IGraph graph)
12 | {
13 | return GetMinVertexCover(graph.ReferenceVertex, new HashSet>(),
14 | new List>());
15 | }
16 |
17 | ///
18 | /// An approximation algorithm for NP complete vertex cover problem.
19 | /// Add a random edge vertices until done visiting all edges.
20 | ///
21 | private List> GetMinVertexCover(IGraphVertex vertex,
22 | HashSet> visited, List> cover)
23 | {
24 | visited.Add(vertex);
25 |
26 | foreach (var edge in vertex.Edges)
27 | {
28 | if (!cover.Contains(vertex) && !cover.Contains(edge.TargetVertex))
29 | {
30 | cover.Add(vertex);
31 | cover.Add(edge.TargetVertex);
32 | }
33 |
34 | if (!visited.Contains(edge.TargetVertex)) GetMinVertexCover(edge.TargetVertex, visited, cover);
35 | }
36 |
37 | return cover;
38 | }
39 | }
--------------------------------------------------------------------------------
/src/Advanced.Algorithms/Graph/Cycle/CycleDetection.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using Advanced.Algorithms.DataStructures.Graph;
3 |
4 | namespace Advanced.Algorithms.Graph;
5 |
6 | ///
7 | /// Cycle detection using Depth First Search.
8 | ///
9 | public class CycleDetector
10 | {
11 | ///
12 | /// Returns true if a cycle exists
13 | ///
14 | public bool HasCycle(IDiGraph graph)
15 | {
16 | var visiting = new HashSet();
17 | var visited = new HashSet();
18 |
19 | foreach (var vertex in graph.VerticesAsEnumberable)
20 | if (!visited.Contains(vertex.Key))
21 | if (Dfs(vertex, visited, visiting))
22 | return true;
23 |
24 | return false;
25 | }
26 |
27 | private bool Dfs(IDiGraphVertex current,
28 | HashSet visited, HashSet visiting)
29 | {
30 | visiting.Add(current.Key);
31 |
32 | foreach (var edge in current.OutEdges)
33 | {
34 | //if we encountered a visiting vertex again
35 | //then their is a cycle
36 | if (visiting.Contains(edge.TargetVertexKey)) return true;
37 |
38 | if (visited.Contains(edge.TargetVertexKey)) continue;
39 |
40 | if (Dfs(edge.TargetVertex, visited, visiting)) return true;
41 | }
42 |
43 | visiting.Remove(current.Key);
44 | visited.Add(current.Key);
45 |
46 | return false;
47 | }
48 | }
--------------------------------------------------------------------------------
/src/Advanced.Algorithms/Graph/Search/BreadthFirst.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using Advanced.Algorithms.DataStructures.Graph;
3 |
4 | namespace Advanced.Algorithms.Graph;
5 |
6 | ///
7 | /// Bread First Search implementation.
8 | ///
9 | public class BreadthFirst
10 | {
11 | ///
12 | /// Returns true if item exists.
13 | ///
14 | public bool Find(IGraph graph, T vertex)
15 | {
16 | return Bfs(graph.ReferenceVertex, new HashSet(), vertex);
17 | }
18 |
19 | ///
20 | /// BFS implementation.
21 | ///
22 | private bool Bfs(IGraphVertex referenceVertex,
23 | HashSet visited, T searchVertex)
24 | {
25 | var bfsQueue = new Queue>();
26 |
27 | bfsQueue.Enqueue(referenceVertex);
28 | visited.Add(referenceVertex.Key);
29 |
30 | while (bfsQueue.Count > 0)
31 | {
32 | var current = bfsQueue.Dequeue();
33 |
34 | if (current.Key.Equals(searchVertex)) return true;
35 |
36 | foreach (var edge in current.Edges)
37 | {
38 | if (visited.Contains(edge.TargetVertexKey)) continue;
39 |
40 | visited.Add(edge.TargetVertexKey);
41 | bfsQueue.Enqueue(edge.TargetVertex);
42 | }
43 | }
44 |
45 | return false;
46 | }
47 | }
--------------------------------------------------------------------------------
/src/Advanced.Algorithms/Graph/Search/DepthFirst.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using Advanced.Algorithms.DataStructures.Graph;
3 |
4 | namespace Advanced.Algorithms.Graph;
5 |
6 | ///
7 | /// Depth First Search.
8 | ///
9 | public class DepthFirst
10 | {
11 | ///
12 | /// Returns true if item exists.
13 | ///
14 | public bool Find(IGraph graph, T vertex)
15 | {
16 | return Dfs(graph.ReferenceVertex, new HashSet(), vertex);
17 | }
18 |
19 | ///
20 | /// Recursive DFS.
21 | ///
22 | private bool Dfs(IGraphVertex current,
23 | HashSet visited, T searchVetex)
24 | {
25 | visited.Add(current.Key);
26 |
27 | if (current.Key.Equals(searchVetex)) return true;
28 |
29 | foreach (var edge in current.Edges)
30 | {
31 | if (visited.Contains(edge.TargetVertexKey)) continue;
32 |
33 | if (Dfs(edge.TargetVertex, visited, searchVetex)) return true;
34 | }
35 |
36 | return false;
37 | }
38 | }
--------------------------------------------------------------------------------
/src/Advanced.Algorithms/Graph/Sort/DepthFirstTopSort.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using Advanced.Algorithms.DataStructures.Graph;
3 |
4 | namespace Advanced.Algorithms.Graph;
5 |
6 | ///
7 | /// Find Toplogical order of a graph using Depth First Search.
8 | ///
9 | public class DepthFirstTopSort
10 | {
11 | ///
12 | /// Returns the vertices in Topologically Sorted Order.
13 | ///
14 | public List GetTopSort(IDiGraph graph)
15 | {
16 | var pathStack = new Stack();
17 | var visited = new HashSet();
18 |
19 | //we need a loop so that we can reach all vertices
20 | foreach (var vertex in graph.VerticesAsEnumberable)
21 | if (!visited.Contains(vertex.Key))
22 | Dfs(vertex, visited, pathStack);
23 |
24 | //now just pop the stack to result
25 | var result = new List();
26 | while (pathStack.Count > 0) result.Add(pathStack.Pop());
27 |
28 | return result;
29 | }
30 |
31 | ///
32 | /// Do a depth first search.
33 | ///
34 | private void Dfs(IDiGraphVertex vertex,
35 | HashSet visited, Stack pathStack)
36 | {
37 | visited.Add(vertex.Key);
38 |
39 | foreach (var edge in vertex.OutEdges)
40 | if (!visited.Contains(edge.TargetVertexKey))
41 | Dfs(edge.TargetVertex, visited, pathStack);
42 |
43 | //add vertex to stack after all edges are visited
44 | pathStack.Push(vertex.Key);
45 | }
46 | }
--------------------------------------------------------------------------------
/src/Advanced.Algorithms/Graph/Sort/KahnTopSort.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using Advanced.Algorithms.DataStructures.Graph;
4 |
5 | namespace Advanced.Algorithms.Graph;
6 |
7 | ///
8 | /// Find Toplogical order of a graph using Kahn's algorithm.
9 | ///
10 | public class KahnsTopSort
11 | {
12 | ///
13 | /// Returns the vertices in Topologically Sorted Order.
14 | ///
15 | public List GetTopSort(IDiGraph graph)
16 | {
17 | var inEdgeMap = new Dictionary();
18 |
19 | var kahnQueue = new Queue();
20 |
21 | foreach (var vertex in graph.VerticesAsEnumberable)
22 | {
23 | inEdgeMap.Add(vertex.Key, vertex.InEdgeCount);
24 |
25 | //init queue with vertices having not in edges
26 | if (vertex.InEdgeCount == 0) kahnQueue.Enqueue(vertex.Key);
27 | }
28 |
29 | //no vertices with zero number of in edges
30 | if (kahnQueue.Count == 0) throw new Exception("Graph has a cycle.");
31 |
32 | var result = new List();
33 |
34 | var visitCount = 0;
35 | //until queue is empty
36 | while (kahnQueue.Count > 0)
37 | {
38 | //cannot exceed vertex number of iterations
39 | if (visitCount > graph.VerticesCount) throw new Exception("Graph has a cycle.");
40 |
41 | //pick a neighbour
42 | var nextPick = graph.GetVertex(kahnQueue.Dequeue());
43 |
44 | //if in edge count is 0 then ready for result
45 | if (inEdgeMap[nextPick.Key] == 0) result.Add(nextPick.Key);
46 |
47 | //decrement in edge count for neighbours
48 | foreach (var edge in nextPick.OutEdges)
49 | {
50 | inEdgeMap[edge.TargetVertexKey]--;
51 | kahnQueue.Enqueue(edge.TargetVertexKey);
52 | }
53 |
54 | visitCount++;
55 | }
56 |
57 | return result;
58 | }
59 | }
--------------------------------------------------------------------------------
/src/Advanced.Algorithms/Numerical/Exponentiation.cs:
--------------------------------------------------------------------------------
1 | namespace Advanced.Algorithms.Numerical;
2 |
3 | ///
4 | /// A fast exponentiation algorithm implementation.
5 | ///
6 | public class FastExponentiation
7 | {
8 | ///
9 | /// Computes exponentiation using squaring.
10 | ///
11 | public static int BySquaring(int @base, int power)
12 | {
13 | while (true)
14 | {
15 | //using the algebraic result
16 | //a^-n = (1/a)^n
17 | if (power < 0)
18 | {
19 | @base = 1 / @base;
20 | power = -power;
21 | continue;
22 | }
23 |
24 | switch (power)
25 | {
26 | case 0:
27 | return 1;
28 | case 1:
29 | return @base;
30 | default:
31 | if (power % 2 == 0)
32 | {
33 | @base = @base * @base;
34 | power = power / 2;
35 | continue;
36 | }
37 | //power is odd
38 | else
39 | {
40 | return @base * BySquaring(@base * @base, (power - 1) / 2);
41 | }
42 | }
43 | }
44 | }
45 | }
--------------------------------------------------------------------------------
/src/Advanced.Algorithms/Numerical/PrimeGenerator.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 |
4 | namespace Advanced.Algorithms.Numerical;
5 |
6 | ///
7 | /// A prime number generation algorithm using Sieve of Eratosthenes.
8 | ///
9 | public class PrimeGenerator
10 | {
11 | public static List GetAllPrimes(int max)
12 | {
13 | var primeTable = new bool[max + 1];
14 |
15 | var sqrt = Math.Sqrt(max);
16 |
17 | for (var i = 2; i < sqrt; i++)
18 | {
19 | //mark multiples of current number as true
20 | if (primeTable[i]) continue;
21 |
22 | for (var j = 2 * i; j <= max; j = j + i) primeTable[j] = true;
23 | }
24 |
25 | //now write back results
26 | var result = new List();
27 |
28 | for (var i = 2; i < primeTable.Length; i++)
29 | if (!primeTable[i])
30 | result.Add(i);
31 |
32 | return result;
33 | }
34 | }
--------------------------------------------------------------------------------
/src/Advanced.Algorithms/Numerical/PrimeTester.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace Advanced.Algorithms.Numerical;
4 |
5 | ///
6 | /// Tests for Prime in School method optimized.
7 | ///
8 | public class PrimeTester
9 | {
10 | ///
11 | /// Check if given number is prime.
12 | ///
13 | public static bool IsPrime(int number)
14 | {
15 | if (number <= 1) return false;
16 |
17 | if (number <= 3) return true;
18 |
19 | //number can be divided by 2 or 3
20 | if (number % 2 == 0 || number % 3 == 0) return false;
21 |
22 | //skip six numbers in each step
23 | //since we don't need to check for 3 even numbers
24 | //and one number divisible by 3
25 | //inside the loop
26 | //check until square root of number
27 | var sqrt = Math.Sqrt(number);
28 | for (var i = 5; i <= sqrt; i = i + 6)
29 | //check for two potential primes
30 | if (number % i == 0 || number % (i + 2) == 0)
31 | return false;
32 |
33 | return true;
34 | }
35 | }
--------------------------------------------------------------------------------
/src/Advanced.Algorithms/Search/BinarySearch.cs:
--------------------------------------------------------------------------------
1 | namespace Advanced.Algorithms.Search;
2 |
3 | ///
4 | /// A binary search algorithm implementation.
5 | ///
6 | public class BinarySearch
7 | {
8 | public static int Search(int[] input, int element)
9 | {
10 | return Search(input, 0, input.Length - 1, element);
11 | }
12 |
13 | private static int Search(int[] input, int i, int j, int element)
14 | {
15 | while (true)
16 | {
17 | if (i == j)
18 | {
19 | if (input[i] == element) return i;
20 |
21 | return -1;
22 | }
23 |
24 | var mid = (i + j) / 2;
25 |
26 | if (input[mid] == element) return mid;
27 |
28 | if (input[mid] > element)
29 | {
30 | j = mid;
31 | continue;
32 | }
33 |
34 | i = mid + 1;
35 | }
36 | }
37 | }
--------------------------------------------------------------------------------
/src/Advanced.Algorithms/Search/BoyerMoore.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 |
5 | namespace Advanced.Algorithms.Search;
6 |
7 | ///
8 | /// A boyer-moore majority finder algorithm implementation.
9 | ///
10 | public class BoyerMoore where T : IComparable
11 | {
12 | public static T FindMajority(IEnumerable input)
13 | {
14 | var candidate = FindMajorityCandidate(input, input.Count());
15 |
16 | if (Verify(input, input.Count(), candidate)) return candidate;
17 |
18 | return default;
19 | }
20 |
21 | //Find majority candidate
22 | private static T FindMajorityCandidate(IEnumerable input, int length)
23 | {
24 | var count = 1;
25 | var candidate = input.First();
26 |
27 | foreach (var element in input.Skip(1))
28 | {
29 | if (candidate.Equals(element))
30 | count++;
31 | else
32 | count--;
33 |
34 | if (count == 0)
35 | {
36 | candidate = element;
37 | count = 1;
38 | }
39 | }
40 |
41 | return candidate;
42 | }
43 |
44 | //verify that candidate is indeed the majority
45 | private static bool Verify(IEnumerable input, int size, T candidate)
46 | {
47 | return input.Count(x => x.Equals(candidate)) > size / 2;
48 | }
49 | }
--------------------------------------------------------------------------------
/src/Advanced.Algorithms/Shared/CustomComparer.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 |
4 | namespace Advanced.Algorithms;
5 |
6 | internal class CustomComparer : IComparer where T : IComparable
7 | {
8 | private readonly IComparer comparer;
9 | private readonly bool isMax;
10 |
11 | internal CustomComparer(SortDirection sortDirection, IComparer comparer)
12 | {
13 | isMax = sortDirection == SortDirection.Descending;
14 | this.comparer = comparer;
15 | }
16 |
17 | public int Compare(T x, T y)
18 | {
19 | return !isMax ? comparer.Compare(x, y) : comparer.Compare(y, x);
20 | }
21 | }
--------------------------------------------------------------------------------
/src/Advanced.Algorithms/Shared/SortDirection.cs:
--------------------------------------------------------------------------------
1 | namespace Advanced.Algorithms;
2 |
3 | public enum SortDirection
4 | {
5 | Ascending = 0,
6 | Descending = 1
7 | }
--------------------------------------------------------------------------------
/src/Advanced.Algorithms/Sorting/BubbleSort.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 |
4 | namespace Advanced.Algorithms.Sorting;
5 |
6 | ///
7 | /// A bubble sort implementation.
8 | ///
9 | public class BubbleSort where T : IComparable
10 | {
11 | ///
12 | /// Time complexity: O(n^2).
13 | ///
14 | public static T[] Sort(T[] array, SortDirection sortDirection = SortDirection.Ascending)
15 | {
16 | var comparer = new CustomComparer(sortDirection, Comparer.Default);
17 | var swapped = true;
18 |
19 | while (swapped)
20 | {
21 | swapped = false;
22 |
23 | for (var i = 0; i < array.Length - 1; i++)
24 | //compare adjacent elements
25 | if (comparer.Compare(array[i], array[i + 1]) > 0)
26 | {
27 | var temp = array[i];
28 | array[i] = array[i + 1];
29 | array[i + 1] = temp;
30 | swapped = true;
31 | }
32 | }
33 |
34 | return array;
35 | }
36 | }
--------------------------------------------------------------------------------
/src/Advanced.Algorithms/Sorting/BucketSort.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 |
5 | namespace Advanced.Algorithms.Sorting;
6 |
7 | ///
8 | /// A bucket sort implementation.
9 | ///
10 | public class BucketSort
11 | {
12 | ///
13 | /// Sort given integers using bucket sort with merge sort as sub sort.
14 | ///
15 | public static int[] Sort(int[] array, int bucketSize, SortDirection sortDirection = SortDirection.Ascending)
16 | {
17 | if (bucketSize < 0 || bucketSize > array.Length) throw new Exception("Invalid bucket size.");
18 |
19 | var buckets = new Dictionary>();
20 |
21 | int i;
22 | for (i = 0; i < array.Length; i++)
23 | {
24 | if (bucketSize == 0) continue;
25 |
26 | var bucketIndex = array[i] / bucketSize;
27 |
28 | if (!buckets.ContainsKey(bucketIndex)) buckets.Add(bucketIndex, new List());
29 |
30 | buckets[bucketIndex].Add(array[i]);
31 | }
32 |
33 | i = 0;
34 | var bucketKeys = new int[buckets.Count];
35 | foreach (var bucket in buckets.ToList())
36 | {
37 | buckets[bucket.Key] = new List(MergeSort
38 | .Sort(bucket.Value.ToArray(), sortDirection));
39 |
40 | bucketKeys[i] = bucket.Key;
41 | i++;
42 | }
43 |
44 | bucketKeys = MergeSort.Sort(bucketKeys, sortDirection);
45 |
46 | var result = new int[array.Length];
47 |
48 | i = 0;
49 | foreach (var bucketKey in bucketKeys)
50 | {
51 | var bucket = buckets[bucketKey];
52 | Array.Copy(bucket.ToArray(), 0, result, i, bucket.Count);
53 | i += bucket.Count;
54 | }
55 |
56 | return result;
57 | }
58 | }
--------------------------------------------------------------------------------
/src/Advanced.Algorithms/Sorting/CountingSort.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 |
4 | namespace Advanced.Algorithms.Sorting;
5 |
6 | ///
7 | /// A counting sort implementation.
8 | ///
9 | public class CountingSort
10 | {
11 | ///
12 | /// Sort given integers.
13 | ///
14 | public static int[] Sort(IEnumerable enumerable, SortDirection sortDirection = SortDirection.Ascending)
15 | {
16 | var lengthAndMax = GetLengthAndMax(enumerable);
17 |
18 | var length = lengthAndMax.Item1;
19 | var max = lengthAndMax.Item2;
20 |
21 | //add one more space for zero
22 | var countArray = new int[max + 1];
23 |
24 | //count the appearances of elements
25 | foreach (var item in enumerable)
26 | {
27 | if (item < 0) throw new Exception("Negative numbers not supported.");
28 |
29 | countArray[item]++;
30 | }
31 |
32 | //now aggregate and assign the sum from left to right
33 | var sum = countArray[0];
34 | for (var i = 1; i <= max; i++)
35 | {
36 | sum += countArray[i];
37 | countArray[i] = sum;
38 | }
39 |
40 | var result = new int[length];
41 |
42 | //now assign result
43 | foreach (var item in enumerable)
44 | {
45 | var index = countArray[item];
46 | result[sortDirection == SortDirection.Ascending ? index - 1 : result.Length - index] = item;
47 | countArray[item]--;
48 | }
49 |
50 | return result;
51 | }
52 |
53 | ///
54 | /// Get Max of given array.
55 | ///
56 | private static Tuple GetLengthAndMax(IEnumerable array)
57 | {
58 | var length = 0;
59 | var max = int.MinValue;
60 | foreach (var item in array)
61 | {
62 | length++;
63 | if (item.CompareTo(max) > 0) max = item;
64 | }
65 |
66 | return new Tuple(length, max);
67 | }
68 | }
--------------------------------------------------------------------------------
/src/Advanced.Algorithms/Sorting/HeapSort.cs:
--------------------------------------------------------------------------------
1 | /* Unmerged change from project 'Advanced.Algorithms (netstandard1.0)'
2 | Before:
3 | using System;
4 | After:
5 | using Advanced.Algorithms.DataStructures;
6 | using System;
7 | */
8 |
9 | using System;
10 | using System.Collections.Generic;
11 | using Advanced.Algorithms.DataStructures;
12 | /* Unmerged change from project 'Advanced.Algorithms (netstandard1.0)'
13 | Before:
14 | using System.Linq;
15 | using Advanced.Algorithms.DataStructures;
16 | After:
17 | using System.Linq;
18 | */
19 |
20 | namespace Advanced.Algorithms.Sorting;
21 |
22 | ///
23 | /// A heap sort implementation.
24 | ///
25 | public class HeapSort where T : IComparable
26 | {
27 | ///
28 | /// Time complexity: O(nlog(n)).
29 | ///
30 | public static T[] Sort(ICollection collection, SortDirection sortDirection = SortDirection.Ascending)
31 | {
32 | //heapify
33 | var heap = new BHeap(sortDirection, collection);
34 |
35 | //now extract min until empty and return them as sorted array
36 | var sortedArray = new T[collection.Count];
37 | var j = 0;
38 | while (heap.Count > 0)
39 | {
40 | sortedArray[j] = heap.Extract();
41 | j++;
42 | }
43 |
44 | return sortedArray;
45 | }
46 | }
--------------------------------------------------------------------------------
/src/Advanced.Algorithms/Sorting/InsertionSort.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 |
4 | namespace Advanced.Algorithms.Sorting;
5 |
6 | ///
7 | /// An insertion sort implementation.
8 | ///
9 | public class InsertionSort where T : IComparable
10 | {
11 | ///
12 | /// Time complexity: O(n^2).
13 | ///
14 | public static T[] Sort(T[] array, SortDirection sortDirection = SortDirection.Ascending)
15 | {
16 | var comparer = new CustomComparer(sortDirection, Comparer.Default);
17 |
18 | for (var i = 0; i < array.Length - 1; i++)
19 | for (var j = i + 1; j > 0; j--)
20 | if (comparer.Compare(array[j], array[j - 1]) < 0)
21 | {
22 | var temp = array[j - 1];
23 | array[j - 1] = array[j];
24 | array[j] = temp;
25 | }
26 | else
27 | {
28 | break;
29 | }
30 |
31 | return array;
32 | }
33 | }
--------------------------------------------------------------------------------
/src/Advanced.Algorithms/Sorting/QuickSort.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 |
4 | namespace Advanced.Algorithms.Sorting;
5 |
6 | ///
7 | /// A quick sort implementation.
8 | ///
9 | public class QuickSort where T : IComparable
10 | {
11 | ///
12 | /// Time complexity: O(n^2)
13 | ///
14 | public static T[] Sort(T[] array, SortDirection sortDirection = SortDirection.Ascending)
15 | {
16 | if (array.Length <= 1) return array;
17 |
18 | var comparer = new CustomComparer(sortDirection, Comparer