Skip to content

Instantly share code, notes, and snippets.

@thomie
Created June 4, 2011 15:37
Show Gist options
  • Save thomie/1007989 to your computer and use it in GitHub Desktop.
Save thomie/1007989 to your computer and use it in GitHub Desktop.
Unique permutations
# Generate all unique permutations of an array
# with possibly duplicate elements (multiset).
# unique_permutations(('A', 'B', 'B')) -> ABB BAB BBA
sub unique_permutations
{
my @results;
my (@list) = @_;
if ($#list == -1) {
return [()];
}
else {
# Create a hash with the unique elements of the list as keys and the index
# of these elements in the list as values.
my %index_hash;
@index_hash{@list} = (0..$#list);
# Loop over the unique elements of the list.
my ($unique_element, $index);
while (($unique_element, $index) = each(%index_hash)) {
# Create a sublist of the list excluding the unique element.
my @sublist = @list;
splice(@sublist, $index, 1);
# Loop over all the permutations of the sublist (recursively).
for my $subpermutations (unique_permutations(@sublist)) {
# Append the unique element to this subpermutation and add the result
# to the final list of results.
push @results, [(@$subpermutations, $unique_element)];
}
}
return @results;
}
}
def unique_permutations(iterable):
# Generate all unique permutations of an iterable
# with possibly duplicate elements (multiset).
# unique_permutations('ABB') -> ABB BAB BBA
if not iterable:
yield []
else:
xs = list(iterable)
for x in set(xs):
i = xs.index(x)
for result in unique_permutations(xs[:i] + xs[i + 1:]):
yield result + [x]
@thomie
Copy link
Author

thomie commented Jun 4, 2011

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