%mathpiper,def="CombinationsList"

/*
    The algorithm this function uses is on pp. 299-300 of
    "Discrete Mathematics and Its Applications" (fourth edition)
    by Kenneth H. Rosen.
*/
CombinationsList(inputList, r) :=
[
    Local(n,manipulatedIndexes,totalCombinations,combinationsList,combinationsLeft,combination,i,j,currentIndexes);
    
    Check(IsList(inputList) And Length(inputList) >= 1, "Argument", "The first argument must be a list with 1 or more elements.");
    
    n := Length(inputList);
    
    Check(r <= n , "Argument", "The second argument must be <= the length of the list.");
    
    manipulatedIndexes := 1 .. r; 
    
    totalCombinations := Combinations(n,r);
    
    combinationsLeft := totalCombinations;
    
    combinationsList := {};
    
    While(combinationsLeft > 0)
    [
        combination := {};
      
        if(combinationsLeft = totalCombinations) 
        [ 
          combinationsLeft := combinationsLeft - 1;
          
          currentIndexes := manipulatedIndexes;
        ]
        else
        [
            i := r;
        
            While(manipulatedIndexes[i] = n - r + i) 
            [
              i--;
            ];
            
            manipulatedIndexes[i] := manipulatedIndexes[i] + 1;
            
            For(j := i + 1, j <= r, j++) 
            [
              manipulatedIndexes[j] := manipulatedIndexes[i] + j - i;
            ];
        
            combinationsLeft := combinationsLeft - 1;
            
            currentIndexes := manipulatedIndexes;
        ];

        For(i := 1, i <= Length(currentIndexes), i++) 
        [
            combination := Append(combination,(inputList[currentIndexes[i]]));
        ];
      
        combinationsList := Append(combinationsList,combination);
    ];
    
    combinationsList;
];


%/mathpiper

    %output,preserve="false"
      Result: True
.   %/output







%mathpiper_docs,name="CombinationsList",categories="User Functions;Combinatorics",access="experimental"
*CMD CombinationsList --- return all of the combinations from a given list taken r at a time
*CALL
	CombinationsList(list,r)

*PARMS
{list} -- a list of elements

{r} -- the combinations from {list} are to be taken {r} at a time

*DESC
This function returns a list which contains all of the combinations of the elements in a 
given list taken r elements at a time.

*E.G.
In> CombinationsList({1,2,3},2)
Result: {{1,2},{1,3},{2,3}}

*SEE Combinations, PermutationsList, Permutations, LeviCivita
%/mathpiper_docs

    %output,preserve="false"
      
.   %/output


