From e683641e24b690e008aadfb931fc126d1b4be746 Mon Sep 17 00:00:00 2001 From: Mahdi Hasnat Siyam Date: Sun, 24 Nov 2024 00:57:30 +0600 Subject: [PATCH 1/3] Add trie data structure and tests --- Algorithms.Tests/Algorithms.Tests.fsproj | 8 +--- Algorithms.Tests/DataStructures/Trie.fs | 60 ++++++++++++++++++++++++ Algorithms/Algorithms.fsproj | 8 +--- Algorithms/DataStructures/Trie.fs | 37 +++++++++++++++ 4 files changed, 101 insertions(+), 12 deletions(-) create mode 100644 Algorithms.Tests/DataStructures/Trie.fs create mode 100644 Algorithms/DataStructures/Trie.fs diff --git a/Algorithms.Tests/Algorithms.Tests.fsproj b/Algorithms.Tests/Algorithms.Tests.fsproj index 836da01..53bedfb 100644 --- a/Algorithms.Tests/Algorithms.Tests.fsproj +++ b/Algorithms.Tests/Algorithms.Tests.fsproj @@ -1,5 +1,4 @@ - net6.0 latest @@ -7,15 +6,14 @@ false false - + - @@ -25,9 +23,7 @@ runtime; build; native; contentfiles; analyzers; buildtransitive - - - + \ No newline at end of file diff --git a/Algorithms.Tests/DataStructures/Trie.fs b/Algorithms.Tests/DataStructures/Trie.fs new file mode 100644 index 0000000..7e2ad16 --- /dev/null +++ b/Algorithms.Tests/DataStructures/Trie.fs @@ -0,0 +1,60 @@ +namespace Algorithms.Tests.DataStructures + +open Microsoft.VisualStudio.TestTools.UnitTesting +open Algorithms.DataStructures.Trie + +[] +type TrieTests () = + + [] + member this.``Test insertion and retrieval with strings``() = + let mutable trie = empty + + trie <- insert "foo" trie + Assert.IsTrue(search "foo" trie) + + trie <- insert "foobar" trie + Assert.IsTrue(search "foobar" trie) + Assert.IsTrue(search "foo" trie) + + trie <- insert "bar" trie + Assert.IsTrue(search "bar" trie) + Assert.IsFalse(search "baz" trie) + Assert.IsFalse(search "foobarbaz" trie) + + [] + member this.``Test empty trie``() = + let trie = empty + Assert.IsFalse(search "foo" trie) + Assert.IsFalse(search "" trie) + + [] + member this.``Test insert empty key``() = + let mutable trie = empty + + trie <- insert "" trie + Assert.IsTrue(search "" trie) + Assert.IsFalse(search "foo" trie) + + [] + member this.``Test overlapping keys``() = + let mutable trie = empty + + trie <- insert "car" trie + trie <- insert "cart" trie + trie <- insert "carter" trie + + Assert.IsTrue(search "car" trie) + Assert.IsTrue(search "cart" trie) + Assert.IsTrue(search "carter" trie) + Assert.IsFalse(search "care" trie) + + [] + member this.``Test partial match``() = + let mutable trie = empty + + trie <- insert "apple" trie + Assert.IsFalse(search "app" trie) + Assert.IsFalse(search "appl" trie) + Assert.IsTrue(search "apple" trie) + Assert.IsFalse(search "applepie" trie) \ No newline at end of file diff --git a/Algorithms/Algorithms.fsproj b/Algorithms/Algorithms.fsproj index b17144c..2bf18dc 100644 --- a/Algorithms/Algorithms.fsproj +++ b/Algorithms/Algorithms.fsproj @@ -1,22 +1,18 @@ - - Library net6.0 latest true - TRACE - + - - + \ No newline at end of file diff --git a/Algorithms/DataStructures/Trie.fs b/Algorithms/DataStructures/Trie.fs new file mode 100644 index 0000000..a7cf29e --- /dev/null +++ b/Algorithms/DataStructures/Trie.fs @@ -0,0 +1,37 @@ +namespace Algorithms.DataStructures + +module Trie = + + type Trie = { + IsWord : bool + Children : Map + } + + let empty : Trie = { IsWord = false; Children = Map.empty } + + let insert (word: string) (trie: Trie) : Trie = + let rec insertImpl (chars: char list) (trie: Trie) : Trie = + match chars with + | [] -> + { trie with IsWord = true } + | c :: rest -> + match trie.Children.TryFind c with + | Some child -> + let child = insertImpl rest child + { trie with Children = trie.Children.Add(c, child) } + | None -> + let child = insertImpl rest empty + { trie with Children = trie.Children.Add(c, child) } + + insertImpl (word |> Seq.toList) trie + + let search (word: string) (trie: Trie) : bool = + let rec searchImpl (chars: char list) (trie: Trie) : bool = + match chars with + | [] -> trie.IsWord + | c :: rest -> + match trie.Children.TryFind c with + | Some child -> searchImpl rest child + | None -> false + searchImpl (word |> Seq.toList) trie + From aed057b84500ce53c6e185d912528f4bf788b270 Mon Sep 17 00:00:00 2001 From: mahdihasnat Date: Sat, 23 Nov 2024 18:58:36 +0000 Subject: [PATCH 2/3] updating DIRECTORY.md --- DIRECTORY.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/DIRECTORY.md b/DIRECTORY.md index 147f594..cd14151 100644 --- a/DIRECTORY.md +++ b/DIRECTORY.md @@ -1,6 +1,8 @@ # List of all files ## Algorithms.Tests + * Datastructures + * [Trie](https://github.com/TheAlgorithms/F-Sharp/blob/main/Algorithms.Tests/DataStructures/Trie.fs) * Math * [Absmaxtests](https://github.com/TheAlgorithms/F-Sharp/blob/main/Algorithms.Tests/Math/AbsMaxTests.fs) * [Absmintests](https://github.com/TheAlgorithms/F-Sharp/blob/main/Algorithms.Tests/Math/AbsMinTests.fs) @@ -37,6 +39,8 @@ * [Zfunctiontests](https://github.com/TheAlgorithms/F-Sharp/blob/main/Algorithms.Tests/Strings/ZFunctionTests.fs) ## Algorithms + * Datastructures + * [Trie](https://github.com/TheAlgorithms/F-Sharp/blob/main/Algorithms/DataStructures/Trie.fs) * Math * [Abs](https://github.com/TheAlgorithms/F-Sharp/blob/main/Algorithms/Math/Abs.fs) * [Absmax](https://github.com/TheAlgorithms/F-Sharp/blob/main/Algorithms/Math/AbsMax.fs) From 459a294e05fa6083ab687d0ee4dddb5894cc1d6a Mon Sep 17 00:00:00 2001 From: Mahdi Hasnat Siyam Date: Sun, 24 Nov 2024 01:07:58 +0600 Subject: [PATCH 3/3] Remove mutable from some tests --- Algorithms.Tests/DataStructures/Trie.fs | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/Algorithms.Tests/DataStructures/Trie.fs b/Algorithms.Tests/DataStructures/Trie.fs index 7e2ad16..0ab3da2 100644 --- a/Algorithms.Tests/DataStructures/Trie.fs +++ b/Algorithms.Tests/DataStructures/Trie.fs @@ -30,19 +30,20 @@ type TrieTests () = [] member this.``Test insert empty key``() = - let mutable trie = empty + let trie = + empty + |> insert "" - trie <- insert "" trie Assert.IsTrue(search "" trie) Assert.IsFalse(search "foo" trie) [] member this.``Test overlapping keys``() = - let mutable trie = empty - - trie <- insert "car" trie - trie <- insert "cart" trie - trie <- insert "carter" trie + let trie = + empty + |> insert "car" + |> insert "cart" + |> insert "carter" Assert.IsTrue(search "car" trie) Assert.IsTrue(search "cart" trie) @@ -51,9 +52,10 @@ type TrieTests () = [] member this.``Test partial match``() = - let mutable trie = empty + let trie = + empty + |> insert "apple" - trie <- insert "apple" trie Assert.IsFalse(search "app" trie) Assert.IsFalse(search "appl" trie) Assert.IsTrue(search "apple" trie)