I have to write a program which give in output a tuple with: min and max of a not-empty list and the value that appears most often. In particular:
min_max [1;0;-1;2;0;-4] ==> (-4; 2)
min_max: int list -> (int * int)
mode [-1;2;1;2;5;-1;5;5;2] ==> 2
mode: int list -> int
This is the code that I wrote for max (min is almost equal) but how can I do to receive as output a tuple with the two values?
let rec max_list xs =
match xs with
| [] -> failwith "xs" "Empty list"
| [x] -> x
| x1::x2::xs' -> max_list((max2 x1 x2)::xs');;
I'll take the first suggestion from @Mark Seemann's answer and run with it, in order to make it generic, working with any collection type, and handle the case of the empty collection sensibly.
let tryMinMax xs =
Seq.fold (function
| Some(mn, mx) -> fun i -> Some(min mn i, max mx i)
| None -> fun i -> Some(i, i) ) None xs
[1;0;-1;2;0;-4]
|> tryMinMax
// val it : (int * int) option = Some (-4, 2)
For the most frequent part of the question:
let mostFrequent xs =
xs
|> Seq.countBy id
|> Seq.maxBy snd
|> fst
[1;0;-1;2;0;-4]
|> mostFrequent
// val it : int = 0
let minMax xs =
xs
|> List.fold
(fun (mn, mx) i -> min mn i, max mx i)
(System.Int32.MaxValue, System.Int32.MinValue)
Not particularly efficient, but fun to write:
let mode xs =
xs
|> List.groupBy id
|> List.map (fun (i, is) -> i, Seq.length is)
|> List.maxBy snd
|> fst
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With