diff --git a/Tasks/Test/Test.Tests/BinaryTreeTests.fs b/Tasks/Test/Test.Tests/BinaryTreeTests.fs new file mode 100644 index 0000000..b91fe4b --- /dev/null +++ b/Tasks/Test/Test.Tests/BinaryTreeTests.fs @@ -0,0 +1,31 @@ +module BinaryTree.Tests + +open NUnit.Framework +open FsUnit + +[] +let testFilter_EmptyTree_GetEmptyList () = + filter None (fun x -> x > 0) |> _.IsEmpty |> should be True + +[] +let testFilter_SingleElementTree_GetTheTip () = + filter (Tip ("abc", None, None)) (fun s -> s.StartsWith "a") + |> should equal ["abc"] + +[] +let testFilter_NestedTree_GetEvenNumbers () = + let tree = Tip (100, + Tip (0, + Tip (-1, + None, + Tip (15, None, None) + ), + Tip (-124, None, None) + ), + Tip (1000, + Tip (-6, None, None), + None + ) + ) + filter tree (fun x -> x % 2 = 0) + |> should equal [0; -124; 100; -6; 1000] diff --git a/Tasks/Test/Test.Tests/InfiniteSequenceTests.fs b/Tasks/Test/Test.Tests/InfiniteSequenceTests.fs new file mode 100644 index 0000000..2a6c889 --- /dev/null +++ b/Tasks/Test/Test.Tests/InfiniteSequenceTests.fs @@ -0,0 +1,20 @@ +module InfiniteSequence.Tests + +open NUnit.Framework +open FsUnit +open FsCheck +open FsCheck.NUnit + +[] +let anyEvenIndexOfSequenceIsPositive (index: NonNegativeInt) = + match index with + | x when int x % 2 = 0 -> Seq.item (int x) signAlternatingSequence > 0 + | x -> Seq.item (int x) signAlternatingSequence < 0 + +[] +let testSequence_GetFirstNItems () = + signAlternatingSequence + |> Seq.take 12 + |> should equal (seq [1; -2; 3; -4; 5; -6; 7; -8; 9; -10; 11; -12]) + +Check.QuickThrowOnFailure anyEvenIndexOfSequenceIsPositive diff --git a/Tasks/Test/Test.Tests/Program.fs b/Tasks/Test/Test.Tests/Program.fs new file mode 100644 index 0000000..96b133f --- /dev/null +++ b/Tasks/Test/Test.Tests/Program.fs @@ -0,0 +1,4 @@ +module Program + +[] +let main _ = 0 diff --git a/Tasks/Test/Test.Tests/Test.Tests.fsproj b/Tasks/Test/Test.Tests/Test.Tests.fsproj new file mode 100644 index 0000000..eb4dcae --- /dev/null +++ b/Tasks/Test/Test.Tests/Test.Tests.fsproj @@ -0,0 +1,30 @@ + + + + net9.0 + latest + false + false + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Tasks/Test/Test.sln b/Tasks/Test/Test.sln new file mode 100644 index 0000000..9edec8e --- /dev/null +++ b/Tasks/Test/Test.sln @@ -0,0 +1,28 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.0.31903.59 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "Test", "Test\Test.fsproj", "{A1E410C5-287A-40C7-833F-34021FFB093A}" +EndProject +Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "Test.Tests", "Test.Tests\Test.Tests.fsproj", "{0BA19CC2-24D0-45D5-A373-30698C147C27}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {A1E410C5-287A-40C7-833F-34021FFB093A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {A1E410C5-287A-40C7-833F-34021FFB093A}.Debug|Any CPU.Build.0 = Debug|Any CPU + {A1E410C5-287A-40C7-833F-34021FFB093A}.Release|Any CPU.ActiveCfg = Release|Any CPU + {A1E410C5-287A-40C7-833F-34021FFB093A}.Release|Any CPU.Build.0 = Release|Any CPU + {0BA19CC2-24D0-45D5-A373-30698C147C27}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {0BA19CC2-24D0-45D5-A373-30698C147C27}.Debug|Any CPU.Build.0 = Debug|Any CPU + {0BA19CC2-24D0-45D5-A373-30698C147C27}.Release|Any CPU.ActiveCfg = Release|Any CPU + {0BA19CC2-24D0-45D5-A373-30698C147C27}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection +EndGlobal diff --git a/Tasks/Test/Test/BinaryTree.fs b/Tasks/Test/Test/BinaryTree.fs new file mode 100644 index 0000000..b662979 --- /dev/null +++ b/Tasks/Test/Test/BinaryTree.fs @@ -0,0 +1,25 @@ +module BinaryTree + +/// Definition of a binary tree. +type Tree<'a> = + | None + | Tip of 'a * Tree<'a> * Tree<'a> + +/// Get all of the elements of the given `tree` for which the `condition` is true. +let filter (tree: Tree<'a>) (condition: 'a -> bool) = + + /// Traverse the `tree` in CPS. + let rec filterInternal (tree: Tree<'a>) (condition: 'a -> bool) (cont: unit -> 'a list) = + match tree with + | None -> cont () + | Tip (x, left, right) -> + if condition x then + filterInternal left condition (fun () -> + x :: filterInternal right condition cont + ) + else + filterInternal left condition (fun () -> + filterInternal right condition cont + ) + + filterInternal tree condition (fun () -> []) diff --git a/Tasks/Test/Test/InfiniteSequence.fs b/Tasks/Test/Test/InfiniteSequence.fs new file mode 100644 index 0000000..058bb36 --- /dev/null +++ b/Tasks/Test/Test/InfiniteSequence.fs @@ -0,0 +1,18 @@ +module InfiniteSequence + +/// A sign alternating sequence of ones. +/// (1, -1, 1, -1, ...) +let signAlternatingOnes = + Seq.initInfinite (( + ) 1) + |> Seq.map (fun x -> + match x with + | x when x % 2 = 0 -> -1 + | _ -> 1 + ) + +/// A sign alternating sequence with ascending module. +/// (1, -2, 3, -4, ...) +let signAlternatingSequence = + Seq.initInfinite (( + ) 1) + |> Seq.zip signAlternatingOnes + |> Seq.map (fun (x, y) -> x * y) diff --git a/Tasks/Test/Test/Test.fsproj b/Tasks/Test/Test/Test.fsproj new file mode 100644 index 0000000..f47966e --- /dev/null +++ b/Tasks/Test/Test/Test.fsproj @@ -0,0 +1,13 @@ + + + + net9.0 + true + + + + + + + +