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