Worice
Worice

Reputation: 4037

Sum of biggest values

I am pretty sure the problem is trivial. Unfortunately, I am new to Ocaml programming, then I am looking in the wrong direction, most likely.

I want to create a function sum_largest_values that takes the n biggest values between the inputs and sums them.

My best attempt so far:

utop # let sum_largest_values (x:int)(y:int) = 
if (x > y) || (y > x) then ((+) x y)
else 
0;;

The problem rises when I try to add a third value:

utop # let sum_largest_values (x:int)(y:int)(z:int) = 
if (x > y > z) || (y > x > z) then ((+) x y)
else 
0;;

I cannot define such a function:

Error: This expression has type int but an expression was 
expected of type bool 

Why the third value z makes the function unusable?

Upvotes: 0

Views: 235

Answers (2)

dub stylee
dub stylee

Reputation: 3342

If I am understanding the question correctly, you are wanting to take as input two int list and one int argument, taking the largest n values of the concatenation of the two int lists and summing them?

(* first, make an inner function to store running total *)
let rec sum_largest_inner l n acc =
  match n with
      0 -> acc
    | x -> match l with
               [] -> 0
             | h :: t -> sum_largest_inner t (x-1) (h+acc)

What that function is doing, is taking a single int list and summing the first n values and storing it in acc. This inner function is assuming that the int list is already sorted in descending order, so we want to make sure to pass in a valid int list.

let sum_largest_values x y n =
  let z = List.sort compare (x @ y) in
  sum_largest_inner (List.rev z) n 0

In this function, we append y to x and sort the resulting list z in descending order, then pass the resulting int list to our inner function from above. This function can easily be modified to add a third, fourth, etc. number of lists, which I will leave to you as an exercise :)

This code also doesn't do any safety checking to make sure you pass valid inputs, it assumes that everything is kosher coming in.

Upvotes: 1

Piotr Reszke
Piotr Reszke

Reputation: 1606

If you want to directly compare 3 or more numbers you cannot do it like that:

# 1<2<3;;
File "", line 1, characters 4-5:
Error: This expression has type int but an expression was expected of type bool

You can build more complex conditions:

# (1<2) && (2<3);;
- : bool = true
# ((1<2) && (2<3)) || ((3<4) && (4<5));;
- : bool = true

But getting back to the original problem

sumsqr that takes the n biggest values between the inputs and sums them

You can try to put the numbers in the array or list, sort the list, take n first elements of the sorted list and sum them up.

Upvotes: 1

Related Questions