7

Lets say i have a function definition like this:

let sum (numbers: int list) =
    // code here

What are possible ways to compute a sum of all other elements in numbers list? So if input is [3;5;3;7] result is [(3, 15); (5, 13); (3, 15); (7, 11)].

Im actually interested in any solutions, especially those which use functional approach.

Thanks

Diverclaim
  • 83
  • 1
  • 3
  • 1
    That's neither a sum nor "all other". What you show are the combinations of the list elements – Panagiotis Kanavos Jun 15 '17 at 13:05
  • Possible duplicate of [Combinations and Permutations in F#](https://stackoverflow.com/questions/4495597/combinations-and-permutations-in-f) – Panagiotis Kanavos Jun 15 '17 at 13:06
  • 2
    @PanagiotisKanavos - He's not talking about combinations. He's saying "I want to take this list, and for each item in the list, calculate the sum of (the list with that one item excluded)." Which is not the same as combinations, though his very short example doesn't make that fact very clear. – rmunn Jun 15 '17 at 14:55
  • @rmunn `very clear` that's an understatement – Panagiotis Kanavos Jun 15 '17 at 14:59

2 Answers2

13

You can do this pretty naively by summing the list and then returning a tuple of (x, sum - x) for each element x in the list:

let sum (numbers: int list) : (int * int) list = 
    let s = List.sum numbers
    numbers |> List.map(fun x -> (x, s-x))

let nums = [3;5;3;7]
printfn "%A" (sum nums) // [(3, 15); (5, 13); (3, 15); (7, 11)]
goric
  • 11,491
  • 7
  • 53
  • 69
4

You could apply mapFold and use the state to see if the first occurrence has already been found.

let excludeAndSum (numbers: int list) i = 
    numbers 
    |> Seq.mapFold (fun c i' -> (i', c||i<>i'), c||i=i') false |> fst
    |> Seq.filter snd
    |> Seq.sumBy fst

let sum numbers = 
    List.map (fun i -> i , excludeAndSum numbers i) numbers
Funk
  • 10,976
  • 1
  • 17
  • 33