I want to find maximum, minimum and average in an array without .NET in F#.
I used this code but it is not working:
let mutable max = 0
let arrX = [|9; 11; 3; 4; 5; 6; 7; 8|]
for i in 0 .. arrX.Length - 2 do
if (arrX.[i]) < (arrX.[i+1]) then
max <- arrX.[i]
printfn "%i" max
I fixed your code for max
let mutable max = 0
let arrX= [|9; 11; 3; 4; 5; 6; 7; 8|]
for i in 0 .. arrX.Length - 1 do
if max < (arrX.[i]) then
max <- arrX.[i]
printfn "%i" max
To find max, min and avg, using your approach:
let mutable max = System.Int32.MinValue
let mutable min = System.Int32.MaxValue
let mutable sum = 0
let arrX= [|9; 11; 3; 4; 5; 6; 7; 8|]
for i in 0 .. arrX.Length - 1 do
if max < (arrX.[i]) then
max <- arrX.[i]
printfn "max %i" max
if min > (arrX.[i]) then
min <- arrX.[i]
printfn "min %i" min
sum <- sum + arrX.[i]
printfn "-> max is %i" max
printfn "-> min is %i" min
printfn "-> avg is %f" (float sum / float arrX.Length)
But note you can do just:
let max = Seq.max arrX
let min = Seq.min arrX
let avg = Seq.averageBy float arrX
While the answers already posted are perfectly valid as to why your posted code doesn't work, I would argue that using a loop and a mutable variable isn't very ... functional. So I thought I would post a more F# - idiomatic way of solving it.
You state you "can't use .NET". I am guessing you mean you can't use any of the built-in functions or .NET libraries. Of course, that also means that you can implement them yourself using F# primitives.
One common function in the functional world is fold
, which simply applies a function to all elements of a sequence, while keeping the return of that function in an accumulator. The built-in version is Seq.fold
, but since we can't use that, we'll define one ourselves:
let rec fold accFn arr acc =
match arr with
| [||] -> acc
| _ -> fold accFn arr.[1..] (accFn arr.[0] acc)
This is a recursive function which applies the accFn
function to each element, and then calling itself with the remainder of the array. When it gets passed an empty array, recursion terminates.
When we have that, let's define some simple functions to pass into fold
:
let min x y =
if x < y then x
else y
let max x y =
if x > y then x
else y
let sum x y =
x + y
Once we have that, the solution to the stated problem is simple:
let arrX= [|9; 11; 3; 4; 5; 6; 7; 8|]
let head = arrX.[0]
let avg = (fold sum arrX 0) / arrX.Length
let minValue = fold min arrX head
let maxValue = fold max arrX head
There are some logical problem to calculate max here. And the placement of printfn
will print max each time it changes. The following code works:
let mutable max = 0
let arrX= [|9; 11; 3; 4; 5; 6; 7; 8|]
for i in 0 .. arrX.Length-1 do
if max < arrX.[i] then
max <- arrX.[i]
printfn "%i" max
let ofArray f (a : 'T array) =
let len = a.Length
let rec aux index ret =
if index >= len then
ret
else
aux (index+1) (f a.[index] ret)
aux 1 a.[0]
let maxOfArray (a : 'T array) = ofArray max a
let minOfArray (a : 'T array) = ofArray min a
let inline sumOfArray (a : 'T array) = ofArray (+) a
let main() =
printfn "max: %d" <| maxOfArray arrX
printfn "min: %d" <| minOfArray arrX
printfn "ave: %f" <| (sumOfArray arrX |> float) / (arrX.Length |> float)
do main()