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
+
+
+
+
+
+
+
+
+
+
+
+
+
+