diff --git a/.gitignore b/.gitignore
index bda7064..3db7d94 100755
--- a/.gitignore
+++ b/.gitignore
@@ -36,5 +36,5 @@ run
.gcda
.gcno
-FirstSteps/FirstSteps/bin/*
-FirstSteps/FirstSteps/obj/*
+**/bin/*
+**/obj/*
diff --git a/lastSteps/Tests/Tests.fsproj b/lastSteps/Tests/Tests.fsproj
new file mode 100644
index 0000000..4b886eb
--- /dev/null
+++ b/lastSteps/Tests/Tests.fsproj
@@ -0,0 +1,27 @@
+
+
+
+ Exe
+ netcoreapp2.0
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/lastSteps/Tests/prog.fs b/lastSteps/Tests/prog.fs
new file mode 100644
index 0000000..aa5f9ac
--- /dev/null
+++ b/lastSteps/Tests/prog.fs
@@ -0,0 +1,75 @@
+open NUnit.Framework
+open FsUnit
+open hw
+
+let rec permutations list taken =
+ seq { if Set.count taken = List.length list then yield [] else
+ for l in list do
+ if not (Set.contains l taken) then
+ for perm in permutations list (Set.add l taken) do
+ yield l::perm }
+
+let testIterator (x:List) =
+ let bst = BinaryTree()
+ for t in x do bst.Insert t;
+ let mutable t = 0
+ for it in bst do
+ it |> should equal t
+ t <- t + 1;
+ t |> should equal x.Length
+
+let testFind (x:List) =
+ let bst = BinaryTree()
+ for t in x do bst.Insert t;
+ for i in -1..x.Length do
+ (bst.At i ) |> should equal (not (i < 0 || i >= x.Length))
+
+let testErase (x:List) =
+ for k in -1..x.Length do
+ let bst = BinaryTree()
+ for t in x do bst.Insert t
+ bst.Erase k
+ let mutable t = 0;
+ for p in bst do
+ if t = k then t <- t + 1
+ t |> should equal p
+ t <- t + 1
+
+let randomTest (n) =
+ let bst = BinaryTree()
+ let mutable st = Set.empty
+ for i in 1..n do
+ let el = rnd.Next()
+ if rnd.Next() % 2 = 0 then
+ if Set.contains el st then
+ bst.At el |> should be True
+ else
+ bst.At el |> should be False
+ bst.Insert el
+ bst.At el |> should be True
+ else
+ let sz = bst.Size()
+ if Set.contains el st then
+ bst.At el |> should be True
+ bst.Erase el
+ bst.At el |> should be False
+ bst.Size() |> should equal (sz - 1)
+ else
+ bst.At el |> should be False
+ bst.Erase el
+ bst.At el |> should be False
+ bst.Size() |> should equal sz
+
+[]
+let ``test`` () =
+ let n = 8
+ for x in permutations (List.init n id) Set.empty do
+ testIterator x
+
+ for x in permutations (List.init n id) Set.empty do
+ testFind x
+
+ for x in permutations (List.init (n - 1) id) Set.empty do
+ testErase x
+ for i in 1..100 do
+ randomTest(100)
diff --git a/lastSteps/lastSteps.sln b/lastSteps/lastSteps.sln
new file mode 100644
index 0000000..14ad43f
--- /dev/null
+++ b/lastSteps/lastSteps.sln
@@ -0,0 +1,31 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 15
+VisualStudioVersion = 15.0.27130.2027
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "lastSteps", "lastSteps\lastSteps.fsproj", "{0D1A3D07-30A9-421F-9367-6AD852CF97D5}"
+EndProject
+Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "Tests", "Tests\Tests.fsproj", "{DDA2F794-D1CC-4046-9237-3B2C1F7D7867}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {0D1A3D07-30A9-421F-9367-6AD852CF97D5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {0D1A3D07-30A9-421F-9367-6AD852CF97D5}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {0D1A3D07-30A9-421F-9367-6AD852CF97D5}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {0D1A3D07-30A9-421F-9367-6AD852CF97D5}.Release|Any CPU.Build.0 = Release|Any CPU
+ {DDA2F794-D1CC-4046-9237-3B2C1F7D7867}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {DDA2F794-D1CC-4046-9237-3B2C1F7D7867}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {DDA2F794-D1CC-4046-9237-3B2C1F7D7867}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {DDA2F794-D1CC-4046-9237-3B2C1F7D7867}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {1507EBBF-D6FE-4AEA-B727-11CB0FEC1811}
+ EndGlobalSection
+EndGlobal
diff --git a/lastSteps/lastSteps/lastSteps.fsproj b/lastSteps/lastSteps/lastSteps.fsproj
new file mode 100644
index 0000000..8e969e2
--- /dev/null
+++ b/lastSteps/lastSteps/lastSteps.fsproj
@@ -0,0 +1,16 @@
+
+
+
+ Exe
+ netcoreapp2.0
+
+
+
+
+
+
+
+
+
+
+
diff --git a/lastSteps/lastSteps/prog.fs b/lastSteps/lastSteps/prog.fs
new file mode 100644
index 0000000..23a853e
--- /dev/null
+++ b/lastSteps/lastSteps/prog.fs
@@ -0,0 +1,105 @@
+// Learn more about F# at http://fsharp.org
+module hw
+
+open System
+open System.Collections
+open System.Collections.Generic
+open System.IO
+
+let read = bigint.Parse << Console.ReadLine
+let readInt = Int32.Parse << Console.ReadLine
+let readStr = Console.ReadLine
+let rnd = System.Random()
+
+type Tree<'T> =
+| Tree of 'T * Tree<'T> * Tree<'T>
+| Leaf
+
+///
+/// Implementation of simple binary tree
+///
+type BinaryTree<'T when 'T : comparison>() =
+ let mutable root = Leaf
+ let mutable size = 0
+
+ let iterator () =
+ let rec handle (node : Tree<'T>) =
+ seq {
+ match node with
+ | Tree(curValue, left, right) ->
+ yield! handle left
+ yield curValue
+ yield! handle right
+ | Leaf -> yield! Seq.empty
+ }
+ handle root
+
+ interface IEnumerable<'T> with
+
+ member this.GetEnumerator(): IEnumerator<'T> =
+ iterator().GetEnumerator()
+
+ member this.GetEnumerator(): IEnumerator =
+ iterator().GetEnumerator() :> IEnumerator
+
+ member v.Empty () = size = 0
+
+ member v.Size () = size
+
+ ///
+ /// Inserts an element into the tree.
+ ///
+ member v.Insert (value : 'T) =
+ let rec handle (value : 'T) (node : Tree<'T>) =
+ match node with
+ | Leaf -> Tree(value, Leaf, Leaf)
+ | Tree(curValue, left, right) when value < curValue -> Tree(curValue, handle value left, right)
+ | Tree(curValue, left, right) -> Tree(curValue, left, handle value right)
+ root <- handle value root
+ size <- size + 1
+
+ ///
+ /// Removes an element from the tree, if exists.
+ ///
+ member v.Erase (value : 'T) =
+ let rec cutLeft node =
+ match node with
+ | Tree(value, Leaf, right) -> (value, right)
+ | Tree(value, left, right) ->
+ let (cutted, newChild) = cutLeft left
+ (cutted, Tree(value, newChild, right))
+
+ let rec handle value node =
+ match node with
+ | Leaf ->
+ size <- size + 1;
+ Leaf
+ | Tree(curValue, left, right) when value < curValue -> Tree(curValue, handle value left, right)
+ | Tree(curValue, left, right) when curValue < value -> Tree(curValue, left, handle value right)
+ | Tree(_, left, right) ->
+ if left = Leaf then right
+ elif right = Leaf then left
+ else
+ let (cutted, newChild) = cutLeft right
+ Tree(cutted, left, newChild)
+
+ root <- handle value root
+ size <- size - 1
+
+ ///
+ /// Checks for the presence of an element in the tree.
+ ///
+ member v.At (value : 'T) =
+ let rec handle (value : 'T) (node : Tree<'T>) =
+ match node with
+ | Tree(curValue, left, right) when value < curValue -> handle value left
+ | Tree(curValue, left, right) when curValue < value -> handle value right
+ | Leaf -> false
+ | _ -> true
+ handle value root
+
+(*_*)
+[]
+let main argv =
+
+ 0 // return an integer exit code