Min / Max and the most commonly used list item

I need to write a program that outputs a tuple with: min and max of a non-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 I wrote for max (min is almost equal), but how can I do to get as the output of a tuple with 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');; 
+5
source share
3 answers

I will take the first sentence from @Mark Seemann and start with it to make it general, work with any type of collection and handle the case of an empty collection intelligently.

 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 common 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 
+3
source
 let minMax xs = xs |> List.fold (fun (mn, mx) i -> min mn i, max mx i) (System.Int32.MaxValue, System.Int32.MinValue) 

Not particularly effective, but interesting to write:

 let mode xs = xs |> List.groupBy id |> List.map (fun (i, is) -> i, Seq.length is) |> List.maxBy snd |> fst 
+2
source

Option without using standard modules:

 open System let tryMinMax xs = let rec minMax xs mn mx = match xs with | [] -> mn, mx | h::t -> minMax t (min mn h) (max mx h) match xs with | [] -> None | _ -> Some(minMax xs Int32.MaxValue Int32.MinValue) 

dotnetfiddle

On the second question - show your attempts to solve.

0
source

Source: https://habr.com/ru/post/1235233/


All Articles