Permutations with some identical elements

From Rosetta Code
Revision as of 19:02, 25 July 2019 by rosettacode>Tobega (Created page with "{{draft task}} Sometimes you want to find all permutations of elements where some elements are repeated, e.g. you have 3 red balls, 2 blue balls and one black ball. If you ju...")
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Permutations with some identical elements is a draft programming task. It is not yet considered ready to be promoted as a complete task, for reasons that should be found in its talk page.

Sometimes you want to find all permutations of elements where some elements are repeated, e.g. you have 3 red balls, 2 blue balls and one black ball. If you just do all permutations of the 6 elements, each permutation will be duplicated 12 times where you can't tell that the identical elements have switched places.

Given an input of the form [a1, a2, ..., ak] where ai denotes how many duplicates of element i you should have, each ai > 0 and the sum of all ai is n. You should get n!/a1!a2!...ak! permutations as a result. (You may, of course, denote the elements 0..k-1 if that works better)

For example, the input [2,1] should give results (1,1,2), (1,2,1) and (2,1,1)

Task

List the permutions you get from the input [2, 3, 1]. Optionally output the permutations as strings where the first element is represented by A, the second by B and the third by C (the example result would then be AAB, ABA and BAA).

Related tasks



Tailspin

<lang tailspin> templates distinctPerms

 templates perms
   <[](1)> $it(1) !
   <>
     def elements: $it;
     1..$it::length -> (
       def k: $it;
       def tail: $elements -> [i](
         <?($i <$k>)> $it -> (<[](2..)> $it(2..-1)!) !
         <> $it!
       );
       $tail -> perms -> [$elements($k;1), $it...] !
     ) !
 end perms
 $it -> [i]([1..$it -> $i] !) -> perms !

end distinctPerms

def alpha: ['ABC'...]; [[2,3,1] -> distinctPerms -> '$($alpha($it)...)' ] -> !OUT::write </lang>

Output:
[AABBBC, AABBCB, AABCBB, AACBBB, ABABBC, ABABCB, ABACBB, ABBABC, ABBACB, ABBBAC, ABBBCA, ABBCAB, ABBCBA, ABCABB, ABCBAB, ABCBBA, ACABBB, ACBABB, ACBBAB, ACBBBA, BAABBC, BAABCB, BAACBB, BABABC, BABACB, BABBAC, BABBCA, BABCAB, BABCBA, BACABB, BACBAB, BACBBA, BBAABC, BBAACB, BBABAC, BBABCA, BBACAB, BBACBA, BBBAAC, BBBACA, BBBCAA, BBCAAB, BBCABA, BBCBAA, BCAABB, BCABAB, BCABBA, BCBAAB, BCBABA, BCBBAA, CAABBB, CABABB, CABBAB, CABBBA, CBAABB, CBABAB, CBABBA, CBBAAB, CBBABA, CBBBAA]