Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
  • Loading branch information
Ts-Pytham committed Dec 29, 2022
2 parents 4efc9eb + e48e196 commit defbd35
Show file tree
Hide file tree
Showing 7 changed files with 248 additions and 22 deletions.
109 changes: 109 additions & 0 deletions GenericCollectionsExtension.Tests/Stack/PriorityStackTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
namespace GenericCollectionsExtension.Tests.Stack;

public class PriorityStackTests
{
[Fact]
public void CapacityLessThanZero()
{
Assert.Throws<ArgumentOutOfRangeException>(() =>
{
var stack = new PriorityStack<int>(-1);
});
}

[Fact]
public void CapacityGreaterThanZero()
{
Action test = () =>
{
var stack = new PriorityStack<int>(1);
};

Assert.IsType<Action>(test);
}

[InlineData(new[] { "ho", "la", "ma" }, new[] { 1, 10, 2 }, "la")]
[InlineData(new[] { "Pytham", "MrDave", "Holly" }, new[] { 20, 10, 50 }, "Holly")]
[InlineData(new[] { "Do", "Re", "Mi" }, new[] { 0, 0, 0 }, "Mi")]
public void CheckPriority(string[] items, int[] priority, string value)
{
int len = items.Length;
var stack = new PriorityStack<string>();

for (int i = 0; i != len; ++i)
{
stack.Push(items[i], priority[i]);
}

Assert.Equal(value, stack.Peek());
}

[Fact]
public void PriorityNegative()
{
var stack = new PriorityStack<string>();

var test = () =>
{
stack.Push("Hello", -1);
};

Assert.Throws<NegativeNumberException>(test);
}

[Theory]
[InlineData(new[] { 10f, 0f, 3f }, new[] { 0, 0, 0}, 3f)]
[InlineData(new[] { 20f, 3.5f, 2.99f }, new[] { 50, 10, 0 }, 20f)]
[InlineData(new[] { 1.11f, 2.53f, 3.1415f }, new[] { 10, 20, 5 }, 2.53f)]
[InlineData(new[] { 1.1f, 3f, -0.5f }, new[] { 47, 0, 65 }, -0.5f)]
public void Pop(float[] items, int[] priority, float pop)
{
int len = items.Length;
var stack = new PriorityStack<float>();

for (int i = 0; i != len; ++i)
{
stack.Push(items[i], priority[i]);
}

Assert.True(stack.Pop() == pop);
Assert.True(stack.Count == len - 1);
}

[Theory]
[InlineData(new[] { 10f, 0f, 3f }, new[] { 0, 0, 0 }, 3f)]
[InlineData(new[] { 20f, 3.5f, 2.99f }, new[] { 50, 10, 0 }, 20f)]
[InlineData(new[] { 1.11f, 2.53f, 3.1415f }, new[] { 10, 20, 5 }, 2.53f)]
[InlineData(new[] { 1.1f, 3f, -0.5f }, new[] { 47, 0, 65 }, -0.5f)]
public void Peek(float[] items, int[] priority, float peek)
{
int len = items.Length;
var stack = new PriorityStack<float>();

for (int i = 0; i != len; ++i)
{
stack.Push(items[i], priority[i]);
}

Assert.True(stack.Peek() == peek);
Assert.True(stack.Count == len);
}

[Theory]
[InlineData(new[] { 10f, 0f, 3f }, new[] { 0, 0, 0 }, 3f)]
[InlineData(new[] { 20f, 3.5f, 2.99f }, new[] { 50, 10, 0 }, 20f)]
[InlineData(new[] { 1.11f, 2.53f, 3.1415f }, new[] { 10, 20, 5 }, 2.53f)]
[InlineData(new[] { 1.1f, 3f, -0.5f }, new[] { 47, 0, 65 }, -0.5f)]
public void TryPeek(float[] items, int[] priority, float peek)
{
int len = items.Length;
var stack = new PriorityStack<float>();

for (int i = 0; i != len; ++i)
{
stack.Push(items[i], priority[i]);
}
Assert.True(stack.TryPeek(out float result));
Assert.True(peek == result);
}
}
1 change: 1 addition & 0 deletions GenericCollectionsExtension.Tests/Usings.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
global using GenericCollectionsExtension.Exceptions;
global using GenericCollectionsExtension.Queue;
global using GenericCollectionsExtension.Stack;
global using GenericCollectionsExtension.List;
global using GenericCollectionsExtension.Tree;
global using Xunit;
51 changes: 46 additions & 5 deletions GenericCollectionsExtension/Queue/Deque/Deque.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@ public class Deque<T> : IDeque<T>, IEnumerable<T>
/// </summary>
public int Count { get => _deque.Count; }

/// <inheritdoc cref="IQueue{T}.IsEmpty"/>
public bool IsEmpty { get => Count == 0; }

/// <summary>
/// Gets a value indicating whether the deque is read-only.
/// This property always returns false.
Expand Down Expand Up @@ -76,7 +79,10 @@ public void Add(T item)
/// </summary>
public void Clear()
{
_deque.Clear();
if (!IsEmpty)
{
_deque.Clear();
}
}

/// <summary>
Expand All @@ -88,6 +94,10 @@ public void Clear()
/// </returns>
public bool Contains(T item)
{
if (IsEmpty)
{
return false;
}
return _deque.Contains(item);
}

Expand All @@ -99,18 +109,31 @@ public void CopyTo(T[] array, int arrayIndex)
/// <inheritdoc cref="IQueue{T}.Dequeue"/>
public T Dequeue()
{
if (Count == 0)
if (IsEmpty)
throw new IndexOutOfRangeException();

var value = _deque[0];
_deque.RemoveAt(0);
return value;
}

/// <inheritdoc cref="IQueue{T}.TryDequeue(out T)"/>
public bool TryDequeue(out T result)
{
if (!IsEmpty)
{
result = Dequeue();
return true;
}
result = default;

return false;
}

/// <inheritdoc cref="IDeque{T}.PopLast"/>
public T PopLast()
{
if (Count == 0)
if (IsEmpty)
throw new IndexOutOfRangeException();

var value = _deque[Count - 1];
Expand All @@ -130,16 +153,29 @@ public IEnumerator<T> GetEnumerator()
/// <inheritdoc cref="IQueue{T}.Peek"/>
public T Peek()
{
if (Count == 0)
if (IsEmpty)
throw new IndexOutOfRangeException();

return _deque[0];
}

/// <inheritdoc cref="IQueue{T}.TryPeek(out T)"/>
public bool TryPeek(out T result)
{
if (!IsEmpty)
{
result = _deque[0];
return true;
}

result = default;
return false;
}

/// <inheritdoc cref="IDeque{T}.PeekLast"/>
public T PeekLast()
{
if (Count == 0)
if (IsEmpty)
throw new IndexOutOfRangeException();

return _deque[Count - 1];
Expand Down Expand Up @@ -176,6 +212,11 @@ public void PushLast(T item)
/// </returns>
public bool Remove(T item)
{
if (IsEmpty)
{
return false;
}

return _deque.Remove(item);
}

Expand Down
25 changes: 24 additions & 1 deletion GenericCollectionsExtension/Queue/IQueue.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,17 +16,40 @@ public interface IQueue<T> : ICollection<T>
/// </summary>
int Capacity { get; }

/// <summary>
/// Gets a value indicating whether the queue is empty.
/// </summary>
bool IsEmpty { get; }

/// <summary>
/// Removes and returns the first element in the queue.
/// </summary>
/// <returns>The first element in the queue.</returns>
T Dequeue();

/// <summary>
/// Returns a value that indicates whether there is an object at the beginning of the
/// <see cref="IQueue{T}"/>, and if one is present, copies it to the result parameter,
/// and removes it from the <see cref="IQueue{T}"/>.
/// </summary>
/// <param name="result">If present, the object at the beginning of the <see cref="IQueue{T}"/>; otherwise, the default value of `T`.</param>
/// <returns><see langword="true"/> if the object is successfully removed; <see langword="false"/> if the <see cref="IQueue{T}"/> is empty.</returns>
bool TryDequeue(out T result);

/// <summary>
/// Returns the first element in the queue without removing it.
/// </summary>
/// <returns>The first element in the queue.</returns>
T Peek();

/// <summary>
/// Returns a value that indicates whether there is an object
/// <see cref="IQueue{T}"/>, and if one is present, copies it to the result parameter.
/// The object is not removed from the <see cref="IQueue{T}"/>.
/// </summary>
/// <param name="result">If present, the object at the beginning of the <see cref="IQueue{T}"/>; otherwise, the default value of `T`.</param>
/// <returns><see langword="true"/> if there is an object at the beginning of the <see cref="IQueue{T}"/>; <see langword="false"/> if the <see cref="IQueue{T}"/> is empty.</returns>
bool TryPeek(out T result);
}

}
}
56 changes: 48 additions & 8 deletions GenericCollectionsExtension/Queue/PriorityQueue/PriorityQueue.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,18 @@ public class PriorityQueue<T> : IPriorityQueue<T>, IEnumerable<T>, ICollection<T

public bool IsReadOnly { get => false; }

/// <summary>
/// Gets the maximum number of elements the <see cref="PriorityQueue{T}"/> can hold.
/// If the value is -1, the <see cref="PriorityQueue{T}"/> can hold an unlimited number of elements.
/// </summary>
public int Capacity
{
get;
}

/// <inheritdoc cref="IQueue{T}.IsEmpty"/>
public bool IsEmpty { get => Count == 0; }

/// <summary>
/// Initializes a new instance of the <see cref="PriorityQueue{T}"/> class with default capacity.
/// </summary>
Expand All @@ -53,7 +60,7 @@ public PriorityQueue(int capacity)
}

/// <summary>
/// Adds an element to the queue with the default priority (0).
/// Adds an element to the <see cref="PriorityQueue{T}"/> with the default priority (0).
/// </summary>
/// <param name="item">The element to add to the queue.</param>
public void Add(T item)
Expand All @@ -66,11 +73,19 @@ public void Add(T item)
/// </summary>
public void Clear()
{
_queue.Clear();
if (!IsEmpty)
{
_queue.Clear();
}
}

public bool Contains(T item)
{
if (IsEmpty)
{
return false;
}

return ExistsItem(item) != -1;
}

Expand All @@ -82,14 +97,27 @@ public void CopyTo(T[] array, int arrayIndex)
/// <inheritdoc cref="IQueue{T}.Dequeue"/>
public T Dequeue()
{
if (Count == 0)
if (IsEmpty)
throw new IndexOutOfRangeException();

var value = _queue[0].Value;
_queue.RemoveAt(0);
return value;
}

/// <inheritdoc cref="IQueue{T}.TryDequeue(out T)"/>
public bool TryDequeue(out T result)
{
if (!IsEmpty)
{
result = Dequeue();
return true;
}

result = default;
return false;
}

/// <inheritdoc cref="IPriorityQueue{T}.Enqueue(T, int)"/>
public void Enqueue(T item, int priority)
{
Expand All @@ -103,7 +131,7 @@ public void Enqueue(T item, int priority)
throw new NegativeNumberException();
}
var value = new PriorityObject<T> { Value = item, Priority = priority };
if (_queue.Count == 0)
if (IsEmpty)
{
_queue.Add(value);
}
Expand Down Expand Up @@ -144,24 +172,36 @@ public IEnumerator<T> GetEnumerator()
/// <inheritdoc cref="IQueue{T}.Peek"/>
public T Peek()
{
if (Count == 0)
if (IsEmpty)
throw new IndexOutOfRangeException();

return _queue[0].Value;
}

/// <inheritdoc cref="IQueue{T}.TryPeek(out T)"/>
public bool TryPeek(out T result)
{
if (!IsEmpty)
{
result = Peek();
return true;
}

result = default;
return false;
}

/// <summary>
/// Removes the specified element from the priority queue.
/// If the element is not found in the queue, the method returns false.
/// If the queue is empty, an IndexOutOfRangeException is thrown.
/// </summary>
/// <param name="item">The element to remove from the priority queue.</param>
/// <returns>True if the element is found and removed from the queue, false otherwise.</returns>
/// <exception cref="IndexOutOfRangeException">Thrown if the queue is empty.</exception>
public bool Remove(T item)
{
if (Count == 0)
throw new IndexOutOfRangeException();
if (IsEmpty)
return false;

int index = ExistsItem(item);

Expand Down
Loading

0 comments on commit defbd35

Please sign in to comment.