You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

107 lines
3.6 KiB

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