I’m struggling to write the code, that will calculate sum of int list list. For example, if we consider following list
[[1],[1,5],[7],[2,3,4]]
we can get different possible sums, depending on which integer we choose every time:
[11,12,13,15,16,17]
Can someone give possible ways (not necessary the code) I could solve it?
This is my attempt to make tail-recursive (kinda) version of algorithm with using lists and pattern matching only. It is written in OCaml, not SML and requires ascending order of inner lists
here
possibleSums [[1];[1;5];[7];[2;3;4]];;evaluates toint list = [11; 12; 13; 15; 16; 17]So basically logical steps are:
reversefunction is just an utility to restore order after resulting accumulator is built – usual concept for tail recursive optimisationlistAddfunction to avoid using map utility in constructing summarieslistMergefunction equal to set union to use sorted lists as integer setslistSumsfunction for mapping summation to cartesian product of two setsposibleSumsfunction for final level of mapping summation to full cartesian product of all sets.This algorithm is not just avoiding stack overflow in recursion through TCO, but also providing near optimal solution for this calculation problem.
Also this solution can be further improved with adding premature merge sorting and removing repeating elements from sets, so inner set order is now insignificant:
You can test its efficiency on simple example. Let’s define repeat function for making repetitive lists:
In that case
possibleSums( repeat( repeat 1 30) 30 )will calculate correct singleton answerint list = [30]in no time. While more straightforward solutions (like Jesper’s one) will do it forever.