Skip to content

Instantly share code, notes, and snippets.

@GiorgioRegni
Created January 11, 2011 19:44
Show Gist options
  • Save GiorgioRegni/774988 to your computer and use it in GitHub Desktop.
Save GiorgioRegni/774988 to your computer and use it in GitHub Desktop.
-module(utils).
-export([comball/1]).
-export([comball/2]).
-export([combuniq/1]).
%% Return all combinations of R elements in list L
comb([], _) -> [[]];
comb(_, 0) -> [[]];
comb(L, R) -> [[H|T] || H <- L, T <- comb(L -- [H], R-1)].
%% Return all combinations of R, R-1, R-2... elements in list L
comball(L, R) ->
lists:flatmap(fun(X) -> comb(L, X) end,
lists:seq(1, R)).
%% Return all combinations of R, R-1, R-2... elements in list L, R=length(L)
comball(L) ->
comball(L, length(L)).
%% Return all unique combinations in order
combuniq(L) -> lists:sort(fun(X1,X2) ->
if length(X1)<length(X2) ->
true;
length(X1)>length(X2) ->
false;
true ->
X1 < X2
end
end, lists:usort(lists:map(fun(R) -> lists:sort(R) end,
comball(L)))).
@jedisct1
Copy link

Here's a slightly leaner version, based on a suggestion on twitter:

-module(test).
-export([allowed/1]).

% null case
allowed([]) ->
[];

% single element case
allowed([E]) ->
[[E]];

% allowed for H|T is H only, and all that is allowed for T,
% as well as that same set with H included.
allowed([H|T]) ->
L = allowed(T),
L ++ [[H]] ++ [[H | E] || E <- L].

FP is sometimes utterly frustrating. The easier it is to read, the longer it took to write :)

@GiorgioRegni
Copy link
Author

Thanks! FP is like sculpting, you're happy when there's nothing left to remove :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment