Thread overview
Permutations of array (slice) ?
December 12
Could I get some help with a trivial question, I'm sure? How do pass a slice as a range? This code:

import std.algorithm; // permutations
import std.range; // replicate
import std.stdio; // writeln

int main()
{
    char[] as = replicate(['a'], 5);
    as[0] = 'b';
    foreach (perm; as.permutations)
        writeln(perm);
}

appears to complain (actual error below) that 'as' is not a range.

Using the slice trick "as[]" from:

https://forum.dlang.org/thread/oxohqaicmpteesugsdnk@forum.dlang.org

doesn't help either. Something obvious I'm missing, I hope.

perm.d:8:26: error: none of the overloads of template ‘std.algorithm.iteration.permutations’ are callable using argument types ‘!()(char[])’
    8 |         foreach (perm; as.permutations)
      |                          ^
/usr/lib/gcc/x86_64-linux-gnu/13/include/d/std/algorithm/iteration.d:7919:20: note: Candidate is: ‘permutations(Range)(Range r)’
     with `Range = char[]`
  must satisfy the following constraint:
`       isRandomAccessRange!Range`
 7919 | Permutations!Range permutations(Range)(Range r)
      |                    ^

December 12
On Tuesday, 12 December 2023 at 14:57:48 UTC, Kevin Bailey wrote:
> perm.d:8:26: error: none of the overloads of template ‘std.algorithm.iteration.permutations’ are callable using argument types ‘!()(char[])’
>     8 |         foreach (perm; as.permutations)
>       |                          ^
> /usr/lib/gcc/x86_64-linux-gnu/13/include/d/std/algorithm/iteration.d:7919:20: note: Candidate is: ‘permutations(Range)(Range r)’
>      with `Range = char[]`
>   must satisfy the following constraint:
> `       isRandomAccessRange!Range`
>  7919 | Permutations!Range permutations(Range)(Range r)
>       |                    ^

Because of autodecoding [1], slices of char and wchar are treated by Phobos as bidirectional ranges of dchar. (They are not random-access ranges because UTF-8 and UTF-16 are variable-length encodings.)

To work around this, use std.utf.byChar:

    import std.utf: byChar;
    foreach (perm; as.byChar.permutations)
        writeln(perm);

[1] http://ddili.org/ders/d.en/ranges.html#ix_ranges.decoding,%20automatic
December 12
On Tuesday, 12 December 2023 at 15:20:23 UTC, Paul Backus wrote:
>
> Because of autodecoding [1], slices of char and wchar are treated by Phobos as bidirectional ranges of dchar. (They are not random-access ranges because UTF-8 and UTF-16 are variable-length encodings.)
>
> To work around this, use std.utf.byChar:
>
>     import std.utf: byChar;
>     foreach (perm; as.byChar.permutations)
>         writeln(perm);
>
> [1] http://ddili.org/ders/d.en/ranges.html#ix_ranges.decoding,%20automatic

ah, many thanks, I never would have figured that out.

But unfortunately, the code shown now prints 120 lines of:

baaaa

120 being suspiciously equal to 5!. The documentation[2] seems to imply that this should be:

baaaa
abaaa
...

When I replace the char[] with int[] [2, 1, 1, 1, 1], it produces 120 lines of random arrangements of the input, but mostly just repeating the input.

Clearly it's doing permutations of a separate array of [0, 1, 2, 3, 4], and then replacing each index with the element at that index (or the equivalent) but it's not even doing that right.

I'll play with nextPermutation. I suspect it would have to be implemented the way that I'm expecting.

[2] https://dlang.org/library/std/algorithm/iteration/permutations.html


December 13

On Tuesday, 12 December 2023 at 16:21:46 UTC, Kevin Bailey wrote:

>

On Tuesday, 12 December 2023 at 15:20:23 UTC, Paul Backus wrote:
But unfortunately, the code shown now prints 120 lines of:

baaaa

120 being suspiciously equal to 5!. The documentation[2] seems to imply that this should be:

baaaa
abaaa
...

This code works for me. (The last 20+ lines are aaaab):

import std;
void main() {
    char[] as = replicate(['a'], 5);
    as[0] = 'b';
    foreach (perm; as.byChar.permutations)
        writeln(perm);
}

Try it on https://run.dlang.io/. Maybe there's some issue on your machine?
Also if you use string as = "abcde"; you can see the permutations better.

December 15

On Wednesday, 13 December 2023 at 20:28:11 UTC, Nick Treleaven wrote:

>

This code works for me. (The last 20+ lines are aaaab):

import std;
void main() {
    char[] as = replicate(['a'], 5);
    as[0] = 'b';
    foreach (perm; as.byChar.permutations)
        writeln(perm);
}

Try it on https://run.dlang.io/. Maybe there's some issue on your machine?
Also if you use string as = "abcde"; you can see the permutations better.

Revisiting this, I see that it works now. I suspect that I had

writeln(as);

Nevertheless, nextPermutation() does what I really want, which is:

(given as[4] = 'b')

aaaab
aaaba
aabaa
abaaa
baaaa