Permutations

First, you can just use the built-in method on any list type.

.say for <a b c>.permutations

Output:

a b c
a c b
b a c
b c a
c a b
c b a

Here is some generic code that works with any ordered type. To force lexicographic ordering, change after to gt. To force numeric order, replace it with >.

sub next_perm ( @a is copy ) {
    my $j = @a.end - 1;
    return Nil if --$j < 0 while @a[$j] after @a[$j+1];

    my $aj = @a[$j];
    my $k  = @a.end;
    $k-- while $aj after @a[$k];
    @a[ $j, $k ] .= reverse;

    my $r = @a.end;
    my $s = $j + 1;
    @a[ $r--, $s++ ] .= reverse while $r > $s;
    return @a;
}

.say for [<a b c>], &next_perm ...^ !*;

Output:

Here is another non-recursive implementation, which returns a lazy list. It also works with any type.

Output:

Finally, if you just want zero-based numbers, you can call the built-in function:

Output:

Last updated

Was this helpful?