lab 6 task 5

main
Artem-Darius Weber 6 months ago
parent 9e821f9197
commit 021df22e8a

@ -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

@ -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
[<EntryPoint>]
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

@ -0,0 +1,8 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net7.0</TargetFramework>
</PropertyGroup>
</Project>
Loading…
Cancel
Save