From e001e2d3c78782f6fea2392b9d194a3c38a2cd68 Mon Sep 17 00:00:00 2001 From: bygu4 Date: Fri, 6 Jun 2025 11:29:53 +0300 Subject: [PATCH 1/2] add queue implementation --- Tasks/Test/Test/Queue.fs | 44 +++++++++++++++++++++++++++++++++++++ Tasks/Test/Test/Test.fsproj | 1 + 2 files changed, 45 insertions(+) create mode 100644 Tasks/Test/Test/Queue.fs diff --git a/Tasks/Test/Test/Queue.fs b/Tasks/Test/Test/Queue.fs new file mode 100644 index 0000000..bfef77d --- /dev/null +++ b/Tasks/Test/Test/Queue.fs @@ -0,0 +1,44 @@ +namespace Queue + +open System + +/// Class representing an element in a linked list. +type Node<'a>(value: 'a, next: Node<'a> option) = + let mutable value = value + let mutable next = next + + /// Get the value of the node. + member _.Value () = value + + /// Get the next node of the current one. + member _.Next () = next + + /// Set the next node of the current one. + member _.SetNext (node: Node<'a> option) = next <- node + +/// Class representing a generic queue. +type Queue<'a>() = + let mutable head: Node<'a> option = None + let mutable tail: Node<'a> option = None + + /// Add the given value to the queue. + member _.Enqueue (value: 'a): unit = + let next = Node (value, None) + match tail with + | Some node -> + node.SetNext <| Some next + tail <- Some node + | None -> + head <- Some next + tail <- Some next + + /// Remove the first element from the queue and return its value. + member _.Dequeue (): 'a = + match head with + | Some node -> + let res = node.Value () + head <- node.Next () + if head.IsNone then tail <- None + res + | None -> + raise (new InvalidOperationException "Error on dequeue: queue was empty") diff --git a/Tasks/Test/Test/Test.fsproj b/Tasks/Test/Test/Test.fsproj index f47966e..6aac9fd 100644 --- a/Tasks/Test/Test/Test.fsproj +++ b/Tasks/Test/Test/Test.fsproj @@ -8,6 +8,7 @@ + From c10d02fb97a5d5e69b0782bce893914d67fb4625 Mon Sep 17 00:00:00 2001 From: bygu4 Date: Fri, 6 Jun 2025 12:14:39 +0300 Subject: [PATCH 2/2] add count property, add tests --- Tasks/Test/Test.Tests/QueueTests.fs | 59 +++++++++++++++++++++++++ Tasks/Test/Test.Tests/Test.Tests.fsproj | 1 + Tasks/Test/Test/Queue.fs | 18 +++++--- 3 files changed, 72 insertions(+), 6 deletions(-) create mode 100644 Tasks/Test/Test.Tests/QueueTests.fs diff --git a/Tasks/Test/Test.Tests/QueueTests.fs b/Tasks/Test/Test.Tests/QueueTests.fs new file mode 100644 index 0000000..cdcd541 --- /dev/null +++ b/Tasks/Test/Test.Tests/QueueTests.fs @@ -0,0 +1,59 @@ +module Queue.Tests + +open NUnit.Framework +open FsUnit +open System + +[] +let testEnqueue_AddElements_SizeShouldBeCorrect () = + let queue = new Queue () + queue.Count |> should equal 0 + for x in { 1 .. 100 } do + queue.Enqueue x + queue.Count |> should equal 100 + +[] +let testDequeue_AddEndGetElements_ObtainElementsInOrderOfAddition () = + let queue = new Queue () + queue.Enqueue -100 + queue.Enqueue 42 + queue.Enqueue 0 + queue.Enqueue Int32.MaxValue + queue.Enqueue Int32.MinValue + queue.Dequeue () |> should equal -100 + queue.Dequeue () |> should equal 42 + queue.Dequeue () |> should equal 0 + queue.Count |> should equal 2 + queue.Dequeue () |> should equal Int32.MaxValue + queue.Dequeue () |> should equal Int32.MinValue + queue.Count |> should equal 0 + +[] +let testDequeue_GetFromEmptyQueue_ThrowException () = + let queue = new Queue () + (fun () -> queue.Dequeue () |> ignore) |> should throw typeof + queue.Count |> should equal 0 + +[] +let testDequeue_RemoveAllElementsAndGetFromEmpty_ThrowException () = + let queue = new Queue () + queue.Enqueue 10.0 + queue.Enqueue 12.2 + queue.Dequeue () |> should equal 10.0 + queue.Dequeue () |> should equal 12.2 + (fun () -> queue.Dequeue () |> ignore) |> should throw typeof + queue.Count |> should equal 0 + +[] +let testDequeue_RemoveElementsAndAddNewOnes_ElementsAreAdded () = + let queue = new Queue () + queue.Enqueue "trololo" + queue.Enqueue "" + queue.Dequeue () |> should equal "trololo" + queue.Dequeue () |> should equal "" + queue.Count |> should equal 0 + queue.Enqueue "test" + queue.Enqueue "a" + queue.Count |> should equal 2 + queue.Dequeue () |> should equal "test" + queue.Dequeue () |> should equal "a" diff --git a/Tasks/Test/Test.Tests/Test.Tests.fsproj b/Tasks/Test/Test.Tests/Test.Tests.fsproj index eb4dcae..bbf51c7 100644 --- a/Tasks/Test/Test.Tests/Test.Tests.fsproj +++ b/Tasks/Test/Test.Tests/Test.Tests.fsproj @@ -10,6 +10,7 @@ + diff --git a/Tasks/Test/Test/Queue.fs b/Tasks/Test/Test/Queue.fs index bfef77d..23c8d47 100644 --- a/Tasks/Test/Test/Queue.fs +++ b/Tasks/Test/Test/Queue.fs @@ -8,10 +8,10 @@ type Node<'a>(value: 'a, next: Node<'a> option) = let mutable next = next /// Get the value of the node. - member _.Value () = value + member _.Value: 'a = value /// Get the next node of the current one. - member _.Next () = next + member _.Next: Node<'a> option = next /// Set the next node of the current one. member _.SetNext (node: Node<'a> option) = next <- node @@ -20,25 +20,31 @@ type Node<'a>(value: 'a, next: Node<'a> option) = type Queue<'a>() = let mutable head: Node<'a> option = None let mutable tail: Node<'a> option = None + let mutable count = 0 - /// Add the given value to the queue. + /// Get the size of the queue. + member _.Count: int = count + + /// Add the given `value` to the queue. member _.Enqueue (value: 'a): unit = let next = Node (value, None) match tail with | Some node -> node.SetNext <| Some next - tail <- Some node + tail <- Some next | None -> head <- Some next tail <- Some next + count <- count + 1 /// Remove the first element from the queue and return its value. member _.Dequeue (): 'a = match head with | Some node -> - let res = node.Value () - head <- node.Next () + let res = node.Value + head <- node.Next if head.IsNone then tail <- None + count <- count - 1 res | None -> raise (new InvalidOperationException "Error on dequeue: queue was empty")