diff --git a/lab6/Makefile b/lab6/Makefile index ae7de68..363b63a 100644 --- a/lab6/Makefile +++ b/lab6/Makefile @@ -1,4 +1,4 @@ -.PHONY: run build clean task1 build-task1 clean-task1 task2 build-task2 clean-task2 task3 build-task3 clean-task3 task4 build-task4 clean-task4 task5 build-task5 clean-task5 +.PHONY: run build clean task1 build-task1 clean-task1 task2 build-task2 clean-task2 task3 build-task3 clean-task3 task4 build-task4 clean-task4 task5 build-task5 clean-task5 task6 build-task6 clean-task6 # task1 run: @@ -61,3 +61,13 @@ build-task5: clean-task5: cd task5 && dotnet clean + +# task6 +task6: + cd task6 && dotnet run --project task6.fsproj + +build-task6: + cd task6 && dotnet build + +clean-task6: + cd task6 && dotnet clean diff --git a/lab6/task6/Program.fs b/lab6/task6/Program.fs new file mode 100644 index 0000000..6565a53 --- /dev/null +++ b/lab6/task6/Program.fs @@ -0,0 +1,161 @@ +module Task6 + +open System + +type BinaryTree = + | Empty + | Node of string * BinaryTree * BinaryTree + +let empty = Empty + +let rec insert value tree = + match tree with + | Empty -> Node(value, Empty, Empty) + | Node(v, left, right) -> + if value < v then + Node(v, insert value left, right) + elif value > v then + Node(v, left, insert value right) + else + tree + +let rec contains value tree = + match tree with + | Empty -> false + | Node(v, left, right) -> + if value = v then true + elif value < v then contains value left + else contains value right + +let rec findMin tree = + match tree with + | Empty -> None + | Node(v, Empty, _) -> Some v + | Node(_, left, _) -> findMin left + +let rec findMax tree = + match tree with + | Empty -> None + | Node(v, _, Empty) -> Some v + | Node(_, _, right) -> findMax right + +let rec remove value tree = + match tree with + | Empty -> Empty + | Node(v, left, right) -> + if value < v then + Node(v, remove value left, right) + elif value > v then + Node(v, left, remove value right) + else + match left, right with + | Empty, Empty -> Empty + | Empty, right -> right + | left, Empty -> left + | left, right -> + match findMin right with + | Some minValue -> + Node(minValue, left, remove minValue right) + | None -> left + +let rec inOrder tree = + match tree with + | Empty -> [] + | Node(v, left, right) -> + (inOrder left) @ [v] @ (inOrder right) + +let rec preOrder tree = + match tree with + | Empty -> [] + | Node(v, left, right) -> + [v] @ (preOrder left) @ (preOrder right) + +let rec postOrder tree = + match tree with + | Empty -> [] + | Node(v, left, right) -> + (postOrder left) @ (postOrder right) @ [v] + +let rec height tree = + match tree with + | Empty -> 0 + | Node(_, left, right) -> + 1 + max (height left) (height right) + +let rec size tree = + match tree with + | Empty -> 0 + | Node(_, left, right) -> + 1 + (size left) + (size right) + +let rec map f tree = + match tree with + | Empty -> Empty + | Node(v, left, right) -> + Node(f v, map f left, map f right) + +let rec fold f acc tree = + match tree with + | Empty -> acc + | Node(v, left, right) -> + let leftAcc = fold f acc left + let nodeAcc = f leftAcc v + fold f nodeAcc right + +let rec filter predicate tree = + match tree with + | Empty -> Empty + | Node(v, left, right) -> + let filteredLeft = filter predicate left + let filteredRight = filter predicate right + if predicate v then + Node(v, filteredLeft, filteredRight) + else + let leftList = inOrder filteredLeft + let rightList = inOrder filteredRight + let combinedList = leftList @ rightList + List.fold (fun acc x -> insert x acc) Empty combinedList + +let fromList lst = + List.fold (fun acc x -> insert x acc) Empty lst + +let toList tree = inOrder tree + +[] +let main argv = + let tree1 = empty + |> insert "dog" + |> insert "cat" + |> insert "elephant" + |> insert "bird" + |> insert "fish" + + printfn "Tree contents (in-order): %A" (inOrder tree1) + printfn "Tree contents (pre-order): %A" (preOrder tree1) + printfn "Tree contents (post-order): %A" (postOrder tree1) + + printfn "Contains 'cat': %b" (contains "cat" tree1) + printfn "Contains 'zebra': %b" (contains "zebra" tree1) + + printfn "Min value: %A" (findMin tree1) + printfn "Max value: %A" (findMax tree1) + + printfn "Tree height: %d" (height tree1) + printfn "Tree size: %d" (size tree1) + + let tree2 = remove "cat" tree1 + printfn "After removing 'cat': %A" (inOrder tree2) + + let upperTree = map (fun s -> s.ToUpper()) tree1 + printfn "Uppercase tree: %A" (inOrder upperTree) + + let longWords = filter (fun s -> s.Length > 3) tree1 + printfn "Words longer than 3 chars: %A" (inOrder longWords) + + let wordCount = fold (fun acc _ -> acc + 1) 0 tree1 + printfn "Word count using fold: %d" wordCount + + let listTree = fromList ["apple"; "banana"; "cherry"; "date"] + printfn "Tree from list: %A" (toList listTree) + + 0 \ No newline at end of file diff --git a/lab6/task6/task6.fsproj b/lab6/task6/task6.fsproj new file mode 100644 index 0000000..1cddbd7 --- /dev/null +++ b/lab6/task6/task6.fsproj @@ -0,0 +1,8 @@ + + + + Exe + net7.0 + + + \ No newline at end of file