From 021df22e8ab3ff7ee28597313b17b14c3ca7b097 Mon Sep 17 00:00:00 2001 From: Artem-Darius Weber Date: Fri, 18 Apr 2025 07:11:57 +0300 Subject: [PATCH] lab 6 task 5 --- lab6/Makefile | 12 ++++- lab6/task5/Program.fs | 107 ++++++++++++++++++++++++++++++++++++++++ lab6/task5/task5.fsproj | 8 +++ 3 files changed, 126 insertions(+), 1 deletion(-) create mode 100644 lab6/task5/Program.fs create mode 100644 lab6/task5/task5.fsproj diff --git a/lab6/Makefile b/lab6/Makefile index c72547a..ae7de68 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 +.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 # task1 run: @@ -51,3 +51,13 @@ build-task4: clean-task4: cd task4 && dotnet clean + +# task5 +task5: + cd task5 && dotnet run --project task5.fsproj + +build-task5: + cd task5 && dotnet build + +clean-task5: + cd task5 && dotnet clean diff --git a/lab6/task5/Program.fs b/lab6/task5/Program.fs new file mode 100644 index 0000000..fc01c3b --- /dev/null +++ b/lab6/task5/Program.fs @@ -0,0 +1,107 @@ +module Task5 + +open System + +type ChurchList<'a> = ('a -> 'b -> 'b) -> 'b -> 'b + +let nil : ChurchList<'a> = fun _ z -> z + +let cons (x: 'a) (xs: ChurchList<'a>) : ChurchList<'a> = + fun f z -> f x (xs f z) + +let toList (churchList: ChurchList<'a>) : 'a list = + churchList (fun x acc -> x :: acc) [] + |> List.rev + +let ofList (lst: 'a list) : ChurchList<'a> = + List.foldBack cons lst nil + +let countFrequencies (churchList: ChurchList<'a>) : ('a * int) list when 'a : equality = + let regularList = toList churchList + + let rec countTailRec lst acc = + match lst with + | [] -> acc + | x :: xs -> + let rec updateCount freqList element = + match freqList with + | [] -> [(element, 1)] + | (key, count) :: rest -> + if key = element then + (key, count + 1) :: rest + else + (key, count) :: updateCount rest element + + let newAcc = updateCount acc x + countTailRec xs newAcc + + countTailRec regularList [] + +let findMaxFrequency (frequencies: ('a * int) list) : ('a * int) option = + let rec findMaxTailRec lst currentMax = + match lst with + | [] -> currentMax + | (element, count) :: rest -> + match currentMax with + | None -> findMaxTailRec rest (Some (element, count)) + | Some (_, maxCount) -> + if count > maxCount then + findMaxTailRec rest (Some (element, count)) + else + findMaxTailRec rest currentMax + + findMaxTailRec frequencies None + +let findMostFrequent (churchList: ChurchList<'a>) : 'a option when 'a : equality = + let frequencies = countFrequencies churchList + match findMaxFrequency frequencies with + | Some (element, _) -> Some element + | None -> None + +let getMostFrequentCount (churchList: ChurchList<'a>) : int when 'a : equality = + let frequencies = countFrequencies churchList + match findMaxFrequency frequencies with + | Some (_, count) -> count + | None -> 0 + +[] +let main argv = + let testList1 = ofList [1; 2; 3; 2; 4; 2; 5; 3; 2] + let frequencies1 = countFrequencies testList1 + frequencies1 |> List.iter (fun (elem, count) -> printfn "%A: %d" elem count) + + match findMostFrequent testList1 with + | Some element -> + let count = getMostFrequentCount testList1 + printfn "Most frequent: %A (%d times)" element count + | None -> printfn "Empty list" + + let testList2 = ofList ["apple"; "banana"; "apple"; "cherry"; "banana"; "apple"] + match findMostFrequent testList2 with + | Some element -> + let count = getMostFrequentCount testList2 + printfn "Most frequent string: %A (%d times)" element count + | None -> printfn "Empty list" + + let testList3 = ofList [5; 5; 5; 5] + match findMostFrequent testList3 with + | Some element -> + let count = getMostFrequentCount testList3 + printfn "All same: %A (%d times)" element count + | None -> printfn "Empty list" + + let testList4 = ofList [1; 2; 3; 4; 5] + match findMostFrequent testList4 with + | Some element -> + let count = getMostFrequentCount testList4 + printfn "All unique, first: %A (%d times)" element count + | None -> printfn "Empty list" + + let testList5 = nil + match findMostFrequent testList5 with + | Some element -> + let count = getMostFrequentCount testList5 + printfn "Should not happen: %A (%d times)" element count + | None -> printfn "Empty list handled correctly" + + 0 \ No newline at end of file diff --git a/lab6/task5/task5.fsproj b/lab6/task5/task5.fsproj new file mode 100644 index 0000000..1cddbd7 --- /dev/null +++ b/lab6/task5/task5.fsproj @@ -0,0 +1,8 @@ + + + + Exe + net7.0 + + + \ No newline at end of file