I enjoy reading Tom Moertel’s blog. In his side bar he lists the Programming Fun Challenge. Here is one of the problems:
Combinations. Create a function combinations that, given a list of strings, returns a list of all the strings that can be formed by picking one character from each of the successive input strings. For example, to compute all of the three-digit binary numbers, you could use combinations as follows:combinations ( ["01","01","01"] )
=> ["000","001","010","011","100","101","110","111"]
Combinations means something else to me, so I won’t use that terminology. I’ll call my function cprod. I see the proposed problem as the computation of a cross product of lists. Strings are instances of lists in Erlang, so handling lists handles strings too.
The trick is handle a pair of lists, and the special cases: a single list, and any empty lists which might occur. The general case is then handled by recursion.
-module(crossproduct).
-export([cprod/1]).
%% input is a list of lists.
%% most important case: a pair of lists
cp( [[], _] )-> [];
cp( [_, []] )-> [];
cp([A, B]) ->
[ [X,Y] || X <- A, Y <-B];
%% more than two lists
cp([A, B | Tail]) ->
cp([cp([A,B]) | Tail]).
%% fewer than two lists
cprod([])-> []; %% no lists
cprod([[]])-> []; %% one list, empty
%% one list, non-empty
cprod([A]) ->
[ [X] || X <- A];
%% the general case, two or more lists
cprod([A|Tail])->
[lists:flatten(X) || X <- cp([A|Tail])].

Posts