digitalmars.D.learn - Permutations of array (slice) ?
- Kevin Bailey (27/27) Dec 12 2023 Could I get some help with a trivial question, I'm sure? How do
- Paul Backus (11/22) Dec 12 2023 Because of autodecoding [1], slices of char and wchar are treated
- Kevin Bailey (19/29) Dec 12 2023 ah, many thanks, I never would have figured that out.
- Nick Treleaven (15/23) Dec 13 2023 This code works for me. (The last 20+ lines are `aaaab`):
- Kevin Bailey (11/25) Dec 15 2023 Revisiting this, I see that it works now. I suspect that I had
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)
| ^
Dec 12 2023
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
Dec 12 2023
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
Dec 12 2023
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`): ```d 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.
Dec 13 2023
On Wednesday, 13 December 2023 at 20:28:11 UTC, Nick Treleaven
wrote:
This code works for me. (The last 20+ lines are `aaaab`):
```d
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
Dec 15 2023








Kevin Bailey <keraba yahoo.com>