diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index a6a59da..340cd7a 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -1,9 +1,9 @@ name: Build -on: [push, pull_request] +on: [push] jobs: - build: + build-Windows: runs-on: windows-latest @@ -20,4 +20,21 @@ jobs: - name: Test run: $slnList = Get-ChildItem $foo.FullName -Recurse -Filter '*.sln'; foreach ($file in $slnList) {dotnet test $file.FullName} + build-Ubuntu: + + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v2 + - name: Build + uses: actions/setup-dotnet@v1 + with: + dotnet-version: '6.x' + - name: Restore + run: for f in $(find . -name "*.sln"); do dotnet restore $f; done + - name: Build + run: for f in $(find . -name "*.sln"); do dotnet build $f; done + - name: Test + run: for f in $(find . -name "*.sln"); do dotnet test $f; done + diff --git a/List/List/List/List.sln b/List/List/List/List.sln new file mode 100644 index 0000000..ba5b5d4 --- /dev/null +++ b/List/List/List/List.sln @@ -0,0 +1,31 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.1.32228.430 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "List", "List\List.csproj", "{E452EFCC-D3CF-4F34-86B6-FFF9119434ED}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ListTest", "ListTest\ListTest.csproj", "{D91A340C-44C7-462D-8304-FF4C9E6170FE}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {E452EFCC-D3CF-4F34-86B6-FFF9119434ED}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {E452EFCC-D3CF-4F34-86B6-FFF9119434ED}.Debug|Any CPU.Build.0 = Debug|Any CPU + {E452EFCC-D3CF-4F34-86B6-FFF9119434ED}.Release|Any CPU.ActiveCfg = Release|Any CPU + {E452EFCC-D3CF-4F34-86B6-FFF9119434ED}.Release|Any CPU.Build.0 = Release|Any CPU + {D91A340C-44C7-462D-8304-FF4C9E6170FE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {D91A340C-44C7-462D-8304-FF4C9E6170FE}.Debug|Any CPU.Build.0 = Debug|Any CPU + {D91A340C-44C7-462D-8304-FF4C9E6170FE}.Release|Any CPU.ActiveCfg = Release|Any CPU + {D91A340C-44C7-462D-8304-FF4C9E6170FE}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {8A75F5F0-0627-4DE9-BE2B-FBB251E5CA4F} + EndGlobalSection +EndGlobal diff --git a/List/List/List/List/List.cs b/List/List/List/List/List.cs new file mode 100644 index 0000000..9480100 --- /dev/null +++ b/List/List/List/List/List.cs @@ -0,0 +1,204 @@ +namespace List; + +using System; +using System.Collections.Generic; + +/// +/// Сlass representing a list +/// +/// type of item values in the list +public class SinglyLinkedList where T : IComparable +{ + /// + /// Class for storing list items + /// + private class ListElement + { + public T? Value { get ; set; } + public ListElement? Next { get; set; } + } + + private ListElement? head; + private ListElement? tail; + + /// + /// List size + /// + public int Size { get; private set; } + + /// + /// Function for adding an item to a list + /// + /// T ype of item value in the list + public virtual void Add(T value) + { + if (value == null) + { + return; + } + + Size++; + if (head == null || tail == null) + { + head = new ListElement(); + tail = head; + head.Value = value; + return; + } + + var newTail = new ListElement(); + newTail.Value = value; + tail.Next = newTail; + tail = newTail; + } + + /// + /// Function to remove an item from the list + /// + /// Item position in the list + /// was the item in the list + public virtual bool RemoveAt(int index) + { + if (index >= Size || index < 0) + { + return false; + } + + Size--; + if (index == 0) + { + head = head?.Next; + return true; + } + + var element = head; + ListElement? copyElement = null; + + for (int i = 0; i < index - 1; i++) + { + if (i == index - 1) + { + copyElement = element; + } + + element = element?.Next; + } + + if (element != null && copyElement != null) + { + copyElement.Next = element.Next; + element.Next = null; + } + + return true; + } + + /// + /// Function to remove an item from the list + /// + /// Value to be deleted + /// was the value in the list + public virtual bool Remove(T value) + { + var copyHead = head; + for (int i = 0; i < Size; i++) + { + while (copyHead!= null) + { + if (copyHead != null && value != null && value.Equals(copyHead.Value)) + { + RemoveAt(i); + return true; + } + + copyHead = copyHead?.Next; + } + } + + return false; + } + + /// + /// Function for changing the value of an element by index + /// + /// Item position in the list + /// New value + public virtual bool ChangeElement(int index, T value) + { + if (index >= Size || index < 0) + { + return false; + } + + var element = head; + for (int i = 0; i < index - 1; i++) + { + element = element?.Next; + } + + if (element != null) + { + element.Value = value; + } + + return true; + } + + /// + /// Function for printing a list + /// + public void PrintList() + { + var element = head; + while (element != null) + { + Console.Write($"{element.Value} "); + element = element.Next; + } + + Console.WriteLine(); + } + + /// + /// Function to search for an item in the list + /// + /// Search value + /// Is there an item in the list + public bool Contains(T value) + { + var element = head; + while (element != null) + { + if (value != null && value.CompareTo(element.Value) == 0) + { + return true; + } + + element = element.Next; + } + + return false; + } + + /// + /// Function for clear list + /// + public void ClearList() => head = null; + + public T GetItemByIndex(int index) + { + if (index >= Size || index < 0) + { + throw new ArgumentOutOfRangeException(); + } + + ListElement? element = head; + for (int i = 0; i < index; i++) + { + element = element?.Next; + } + + return element!.Value!; + } + +} \ No newline at end of file diff --git a/List/List/List/List/List.csproj b/List/List/List/List/List.csproj new file mode 100644 index 0000000..16e62dd --- /dev/null +++ b/List/List/List/List/List.csproj @@ -0,0 +1,10 @@ + + + + Library + net6.0 + enable + enable + + + diff --git a/List/List/List/List/RemoveNonExistingElementException.cs b/List/List/List/List/RemoveNonExistingElementException.cs new file mode 100644 index 0000000..1144954 --- /dev/null +++ b/List/List/List/List/RemoveNonExistingElementException.cs @@ -0,0 +1,6 @@ +namespace List; + +/// +/// Exception for the case of deleting a non-existent element +/// +public class RemoveNonExistingElementException : InvalidOperationException { } \ No newline at end of file diff --git a/List/List/List/List/RepeatValueException.cs b/List/List/List/List/RepeatValueException.cs new file mode 100644 index 0000000..4ade6f3 --- /dev/null +++ b/List/List/List/List/RepeatValueException.cs @@ -0,0 +1,6 @@ +namespace List; + +/// +/// Exception for the case of adding an existing element +/// +public class RepeatValueException : InvalidOperationException { } diff --git a/List/List/List/List/UniqueList.cs b/List/List/List/List/UniqueList.cs new file mode 100644 index 0000000..0413598 --- /dev/null +++ b/List/List/List/List/UniqueList.cs @@ -0,0 +1,76 @@ +namespace List; + +/// +/// Class representing a list of unique values +/// +public class UniqueList : SinglyLinkedList where T : IComparable +{ + /// + /// Function for adding an item to a list + /// + /// Type of item value in the list + public override void Add(T value) + { + if (Contains(value)) + { + throw new RepeatValueException(); + } + + base.Add(value); + } + + /// + /// Function to remove an item from the unique list + /// + /// Item position in the list + public override bool RemoveAt(int index) + { + if (!base.RemoveAt(index)) + { + throw new RemoveNonExistingElementException(); + } + + return true; + } + + /// + /// Function to remove an item from the list + /// + /// Value to be deleted + /// was the value in the list + public override bool Remove(T value) + { + if (!base.Remove(value)) + { + throw new RemoveNonExistingElementException(); + } + + return false; + } + + /// + /// Function for changing the value of an element by index + /// + /// Item position in the list + /// New value + public override bool ChangeElement(int index, T value) + { + if (index >= Size || index < 0) + { + return false; + } + + if (base.GetItemByIndex(index).CompareTo(value) == 0) + { + return true; + } + + if (Contains(value)) + { + throw new InvalidOperationException(); + } + + base.ChangeElement(index, value); + return true; + } +} diff --git a/List/List/List/ListTest/ListTest.cs b/List/List/List/ListTest/ListTest.cs new file mode 100644 index 0000000..88ef85f --- /dev/null +++ b/List/List/List/ListTest/ListTest.cs @@ -0,0 +1,97 @@ +namespace ListTest; + +using NUnit.Framework; +using List; +using System; + +public class Tests +{ + private UniqueList list = new(); + + [SetUp] + public void Setup() + { + list = new UniqueList(); + } + + [Test] + public void ShouldExpectedZeroWhenListSizeEqualZero() + { + Assert.AreEqual(0, list.Size); + } + + [Test] + public void ShouldSizeIncrementedWhenSizeAfterAddNonExisintgElement() + { + list.Add(1); + Assert.AreEqual(1, list.Size); + } + + [Test] + public void ShouldThrowsRemoveNonExistingElementExceptionWhenRemoveFromEmptyList() + { + Assert.Throws(() => list.Remove(0)); + } + + [Test] + public void ShouldThrowsRemoveNonExistingElementExceptionWhenRemoveNonExistenElement() + { + list.Add(1); + list.Add(2); + list.Add(0); + list.Add(-12); + Assert.Throws(() => list.Remove(4)); + } + + [Test] + public void ShouldThrowsRepeatValueExceptionWhenAddExistingElement() + { + list.Add(1); + Assert.Throws(() => list.Add(1)); + } + + [Test] + public void ShouldThrowsInvalidOperationExceptionWhenChandeElementWithExistingOne() + { + list.Add(1); + list.Add(2); + Assert.Throws(() => list.ChangeElement(0, 2)); + } + + [Test] + public void ShouldExpectedTrueWhenContainsForExistingElement() + { + list.Add(12); + Assert.AreEqual(true, list.Contains(12)); + } + + [Test] + public void ShouldExpectedFalseWhenContainsForExistingElement() + { + list.Add(2); + Assert.AreEqual(false, list.Contains(10)); + } + + [Test] + public void ShouldExpectedFalseWhenContainsForRemovedElement() + { + list.Add(2); + list.Remove(2); + Assert.AreEqual(false, list.Contains(2)); + } + + [Test] + public void ShouldExpectedFalseWhenChangeNonExistenElement() + { + Assert.AreEqual(false, list.ChangeElement(2, 12)); + } + + [Test] + public void ShouldExpectedFalseWhenContainsChangeReplacedElement() + { + list.Add(125); + list.ChangeElement(0, 12); + Assert.AreEqual(true, list.Contains(12)); + Assert.AreEqual(false, list.Contains(125)); + } +} \ No newline at end of file diff --git a/List/List/List/ListTest/ListTest.csproj b/List/List/List/ListTest/ListTest.csproj new file mode 100644 index 0000000..4cc12ed --- /dev/null +++ b/List/List/List/ListTest/ListTest.csproj @@ -0,0 +1,21 @@ + + + + net6.0 + enable + + false + + + + + + + + + + + + + +