This seems to be your algorithm:
- Create all combinations (2 ^ n)
- Summation of each set of combinations (n)
- List search for each sum (n)
It looks like n*2^n . I think that as fast as you can go in terms of calculations, since you need to try in order of all the combinations for each number in the list. Maybe someone can fix me about this.
However, your cosmic efficiency seems 2^n , since it stores all the combinations that you don't need.
This is what I came up with that only accumulates the results:
- For each item, search the rest of the list for combinations that add to it.
- To find combinations, subtract the first number of the list from the target number and find the rest of the list for combinations that make up the difference.
-module(subsets). -export([find_subsets/1]). find_subsets(NumList) -> ReverseSorted = lists:reverse(lists:sort(NumList)), find_each_subset(ReverseSorted, []). find_each_subset([], Subsets) -> Subsets; find_each_subset([First | ReverseSorted], Subsets) -> [ { First, recurse_find_subsets(First, ReverseSorted, [])} | find_each_subset(ReverseSorted, Subsets)]. recurse_find_subsets(_Target, [], Sets) -> Sets; recurse_find_subsets(Target, [Target | _Numbers], []) -> [[Target]]; recurse_find_subsets(Target, [First | Numbers], Sets) when Target - First > 0 -> Subsets = recurse_find_subsets(Target - First, Numbers, []), NewSets = lists:map(fun(Subset) -> [ First | Subset] end, Subsets), recurse_find_subsets(Target, Numbers, lists:append(NewSets, Sets)); recurse_find_subsets(Target, [_First | Numbers], Sets) -> recurse_find_subsets(Target, Numbers, Sets).
Output:
5> subsets:find_subsets([6,4,3,2,1]). [{6,[[3,2,1],[4,2]]},{4,[[3,1]]},{3,[[2,1]]},{2,[]},{1,[]}]