diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml
new file mode 100644
index 0000000..94ac0b1
--- /dev/null
+++ b/.github/workflows/dotnet.yml
@@ -0,0 +1,38 @@
+name: Build
+
+on: [push]
+
+jobs:
+ build-Windows:
+
+ runs-on: windows-latest
+
+ steps:
+ - uses: actions/checkout@v2
+ - name: Build
+ uses: actions/setup-dotnet@v1
+ with:
+ dotnet-version: '6.x'
+ - name: Restore
+ run: $slnList = Get-ChildItem $foo.FullName -Recurse -Filter '*.sln'; foreach ($file in $slnList) {nuget restore $file.FullName}
+ - name: Build
+ run: $slnList = Get-ChildItem $foo.FullName -Recurse -Filter '*.sln'; foreach ($file in $slnList) {dotnet build $file.FullName}
+ - 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
\ No newline at end of file
diff --git a/Homework2/Bor/Bor.sln b/Homework2/Bor/Bor.sln
new file mode 100644
index 0000000..66a4364
--- /dev/null
+++ b/Homework2/Bor/Bor.sln
@@ -0,0 +1,31 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 17
+VisualStudioVersion = 17.1.32210.238
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Bor", "Bor\Bor.csproj", "{A5948E4C-54A6-49B2-AD93-A2C768CF3B7B}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BorTest", "BorTest\BorTest.csproj", "{82DAD3CF-7041-4300-B987-4CF0FD1C3E52}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {A5948E4C-54A6-49B2-AD93-A2C768CF3B7B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {A5948E4C-54A6-49B2-AD93-A2C768CF3B7B}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {A5948E4C-54A6-49B2-AD93-A2C768CF3B7B}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {A5948E4C-54A6-49B2-AD93-A2C768CF3B7B}.Release|Any CPU.Build.0 = Release|Any CPU
+ {82DAD3CF-7041-4300-B987-4CF0FD1C3E52}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {82DAD3CF-7041-4300-B987-4CF0FD1C3E52}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {82DAD3CF-7041-4300-B987-4CF0FD1C3E52}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {82DAD3CF-7041-4300-B987-4CF0FD1C3E52}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {EEBE94E6-045F-4E20-8C45-A352B7E2EEA7}
+ EndGlobalSection
+EndGlobal
diff --git a/Homework2/Bor/Bor/Bor.csproj b/Homework2/Bor/Bor/Bor.csproj
new file mode 100644
index 0000000..644c780
--- /dev/null
+++ b/Homework2/Bor/Bor/Bor.csproj
@@ -0,0 +1,10 @@
+
+
+
+ Library
+ net6.0
+ enable
+ enable
+
+
+
diff --git a/Homework2/Bor/Bor/Trie.cs b/Homework2/Bor/Bor/Trie.cs
new file mode 100644
index 0000000..5bf2180
--- /dev/null
+++ b/Homework2/Bor/Bor/Trie.cs
@@ -0,0 +1,180 @@
+namespace Trie;
+
+///
+/// A class representing the Trie
+///
+public class Trie
+{
+ ///
+ /// A class representing the Trie node
+ ///
+ private class Node
+ {
+ ///
+ /// Dictionary for storing characters for each node
+ ///
+ public Dictionary Nodes = new();
+
+ ///
+ /// Node property - whether it is the end of a string
+ ///
+ public bool IsTerminal { get; set; }
+ }
+
+ ///
+ /// Bor root
+ ///
+ private readonly Node root = new();
+
+ ///
+ /// Bor size
+ ///
+ public int Size { get; private set; }
+
+ ///
+ /// Function for adding a string
+ ///
+ /// Element to add
+ /// Was there an element string before calling Add
+ public bool Add(string element)
+ {
+ if (Contains(element))
+ {
+ return false;
+ }
+
+ Node node = root;
+ for (int i = 0; i < element.Length; i++)
+ {
+ if (node != null && !node.Nodes.ContainsKey(element[i]))
+ {
+ node.Nodes.Add(element[i], new Node());
+ Size++;
+ }
+
+ if (node != null && node.Nodes.ContainsKey(element[i]))
+ {
+ node = node.Nodes[element[i]];
+ }
+ }
+
+ if (node != null)
+ {
+ node.IsTerminal = true;
+ }
+
+ return true;
+ }
+
+ ///
+ /// Is the string contained in the Trie
+ ///
+ /// Element to search
+ /// True if there is such a string. False if there is no such string
+ public bool Contains(string element)
+ {
+ Node? node = root;
+ for (int i = 0; i < element.Length; i++)
+ {
+ if (node.Nodes.TryGetValue(element[i], out node))
+ {
+ continue;
+ }
+
+ return false;
+ }
+
+ return node.IsTerminal;
+ }
+
+ ///
+ /// Function for finding the number of strings starting with a prefix
+ ///
+ /// The number of strings starting with the prefix
+ public int HowManyStartWithPrefix(string prefix)
+ {
+ Node? node = root;
+ for (int i = 0; i < prefix.Length; i++)
+ {
+ if (node != null)
+ {
+ if (node.Nodes.TryGetValue(prefix[i], out node))
+ {
+ continue;
+ }
+ }
+
+ return 0;
+ }
+
+ if (node == null)
+ {
+ return 0;
+ }
+
+ return node.IsTerminal ? 1 + node.Nodes.Count : node.Nodes.Count;
+ }
+
+ ///
+ /// Function for clearing dictionaries
+ ///
+ ///
+ static private void ClearDictionaryAndNode(Node node)
+ {
+ node.Nodes.Clear();
+ }
+
+ ///
+ /// Function for deleting string from Trie
+ ///
+ /// Element to delete
+ /// as there an element string before calling Remove
+ public bool Remove(string element)
+ {
+ if (!Contains(element))
+ {
+ return false;
+ }
+
+ int index = 0;
+ Node node = root;
+ Node? parent = null;
+ for (int i = 0; i < element.Length; i++)
+ {
+ if (node != null)
+ {
+ node = node.Nodes[element[i]];
+
+ if (node.Nodes.Count == 0 && i == element.Length - 1)
+ {
+ if (parent != null)
+ {
+ ClearDictionaryAndNode(parent);
+ Size -= i - index;
+ return true;
+ }
+ else
+ {
+ ClearDictionaryAndNode(root);
+ Size = 0;
+ return true;
+ }
+ }
+
+ if (node.Nodes.Count != 0 && i == element.Length - 1)
+ {
+ node.IsTerminal = false;
+ return true;
+ }
+ }
+
+ if (node != null && node.IsTerminal)
+ {
+ index = i;
+ parent = node;
+ }
+ }
+
+ return true;
+ }
+}
diff --git a/Homework2/Bor/Bor/Trie.csproj b/Homework2/Bor/Bor/Trie.csproj
new file mode 100644
index 0000000..644c780
--- /dev/null
+++ b/Homework2/Bor/Bor/Trie.csproj
@@ -0,0 +1,10 @@
+
+
+
+ Library
+ net6.0
+ enable
+ enable
+
+
+
diff --git a/Homework2/Bor/BorTest/BorTest.csproj b/Homework2/Bor/BorTest/BorTest.csproj
new file mode 100644
index 0000000..534cb0f
--- /dev/null
+++ b/Homework2/Bor/BorTest/BorTest.csproj
@@ -0,0 +1,21 @@
+
+
+
+ net6.0
+ enable
+
+ false
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Homework2/Bor/BorTest/TrieTest.cs b/Homework2/Bor/BorTest/TrieTest.cs
new file mode 100644
index 0000000..c27b471
--- /dev/null
+++ b/Homework2/Bor/BorTest/TrieTest.cs
@@ -0,0 +1,97 @@
+namespace TrieTest;
+
+using NUnit.Framework;
+using Trie;
+
+public class TrieTest
+{
+ private Trie trie = new();
+
+ [SetUp]
+ public void Setup()
+ {
+ trie = new();
+ }
+
+ [Test]
+ public void ShouldExpectedFalseWhenRemoveFromEmptyBor()
+ {
+ Assert.IsFalse(trie.Remove("hello"));
+ }
+
+ [Test]
+ public void ShouldExpectedFalseWhenAddExistingString()
+ {
+ Assert.IsTrue(trie.Add("hello"));
+ Assert.IsFalse(trie.Add("hello"));
+ }
+
+ [Test]
+ public void ShouldExpectedFalseWhenContainsForNonExistingString()
+ {
+ Assert.IsFalse(trie.Contains("hello"));
+ }
+
+ [Test]
+ public void ShouldExpectedTrueWhenContainsForExistingString()
+ {
+ Assert.IsTrue(trie.Add("hello"));
+ Assert.IsTrue(trie.Contains("hello"));
+ }
+
+ [Test]
+ public void ShouldExpectedFalseWhenRemoveForRemovedString()
+ {
+ Assert.IsTrue(trie.Add("hello"));
+ Assert.IsTrue(trie.Remove("hello"));
+ Assert.IsFalse(trie.Remove("hello"));
+ }
+
+ [Test]
+ public void ShouldExpectedFalseWhenContainsForRemovedString()
+ {
+ Assert.IsTrue(trie.Add("hello"));
+ Assert.IsTrue(trie.Remove("hello"));
+ Assert.IsFalse(trie.Contains("hello"));
+ }
+
+ [Test]
+ public void ShouldExpected5WhenSizeForBorContains5Node()
+ {
+ Assert.IsTrue(trie.Add("hello"));
+ Assert.AreEqual(5, trie.Size);
+ }
+
+ [Test]
+ public void ShouldBorSizeNotChangeWhenAddExistingSubstring()
+ {
+ Assert.IsTrue(trie.Add("hello"));
+ int size = trie.Size;
+ Assert.IsTrue(trie.Add("hell"));
+ Assert.AreEqual(size, trie.Size);
+ }
+
+ [Test]
+ public void ShouldBorSizeEqual8WhenAddStringLength3WithNonExistingFirstSymbolForBorContains5Node()
+ {
+ Assert.IsTrue(trie.Add("hello"));
+ Assert.IsTrue(trie.Add("bye"));
+ Assert.AreEqual(8, trie.Size);
+ }
+
+ [Test]
+ public void ShouldExpected2WhenHowManyStartWithPrefixForBorContains2StringWhichStartWithSamePrefix()
+ {
+ Assert.IsTrue(trie.Add("hello"));
+ Assert.IsTrue(trie.Add("hel"));
+ Assert.AreEqual(2, trie.HowManyStartWithPrefix("hel"));
+ }
+
+ [Test]
+ public void ShouldExpected0WhenHowManyStartWithPrefixForNonExistingPrefix()
+ {
+ Assert.IsTrue(trie.Add("hello"));
+ Assert.IsTrue(trie.Add("bye"));
+ Assert.AreEqual(0, trie.HowManyStartWithPrefix("leee"));
+ }
+}
\ No newline at end of file