Jump to page: 1 2 3
Thread overview
shuffle a character array
Jul 20, 2016
celavek
Jul 20, 2016
Mike Parker
Jul 20, 2016
Mike Parker
Jul 20, 2016
Mike Parker
Jul 20, 2016
celavek
Jul 20, 2016
Mike Parker
Jul 20, 2016
celavek
Jul 20, 2016
pineapple
Jul 20, 2016
Mike Parker
Jul 20, 2016
pineapple
Jul 20, 2016
pineapple
Jul 20, 2016
pineapple
Jul 20, 2016
Mike Parker
Jul 20, 2016
ag0aep6g
Jul 20, 2016
Jesse Phillips
Jul 21, 2016
pineapple
Jul 20, 2016
ketmar
Jul 20, 2016
Ali Çehreli
Jul 20, 2016
ketmar
Jul 20, 2016
Jack Stouffer
Jul 20, 2016
Ali Çehreli
Jul 21, 2016
Mike Parker
Jul 20, 2016
celavek
July 20, 2016
Hi

I'm trying to shuffle a character array but I get some compilation errors.

*
char[] upper = std.ascii.uppercase.dup;
randomShuffle!(typeof(upper))(upper);

randomShuffle(upper);

example.d(34): Error: template std.random.randomShuffle cannot deduce function from argument types !(char[])(char[]), candidates are:
/usr/include/dmd/phobos/std/random.d(1822):        std.random.randomShuffle(Range, RandomGen)(Range r, ref RandomGen gen) if (isRandomAccessRange!Range && isUniformRNG!RandomGen)
/usr/include/dmd/phobos/std/random.d(1829):        std.random.randomShuffle(Range)(Range r) if (isRandomAccessRange!Range)

example.d(34): Error: template std.random.randomShuffle cannot deduce function from argument types !()(char[]), candidates are:
/usr/include/dmd/phobos/std/random.d(1822):        std.random.randomShuffle(Range, RandomGen)(Range r, ref RandomGen gen) if (isRandomAccessRange!Range && isUniformRNG!RandomGen)
/usr/include/dmd/phobos/std/random.d(1829):        std.random.randomShuffle(Range)(Range r) if (isRandomAccessRange!Range)
*

I thought that I could use a dynamic array as a range ...

July 20, 2016
On Wednesday, 20 July 2016 at 07:49:38 UTC, celavek wrote:

>
> I thought that I could use a dynamic array as a range ...

You can. However, if you take a look at the documentation for std.random.randomShuffle [1], you'll find the following constraint:

if (isRandomAccessRange!Range);

You can then go to the documentation for std.range.primitives.isRandomAccessRange [2], where you'll find the following:

"Although char[] and wchar[] (as well as their qualified versions including string and wstring) are arrays, isRandomAccessRange yields false for them because they use variable-length encodings (UTF-8 and UTF-16 respectively). These types are bidirectional ranges only."

If you are absolutely, 100% certain that you are dealing with ASCII, you can do this:

```
import std.string : representation;
randomShuffle(charArray.representation);

That will give you a ubyte[] for char[] and a ushort[] for wchar[].

[1] https://dlang.org/phobos/std_random.html#.randomShuffle
[2] https://dlang.org/phobos/std_range_primitives.html#isRandomAccessRange


July 20, 2016
On Wednesday, 20 July 2016 at 08:02:07 UTC, Mike Parker wrote:
> On Wednesday, 20 July 2016 at 07:49:38 UTC, celavek wrote:

> If you are absolutely, 100% certain that you are dealing with ASCII, you can do this:
>

And I forgot to add:

Otherwise, you'll want to convert to dchar[] (probably via std.utf.toUTF32) and pass that along instead.
July 20, 2016
On Wednesday, 20 July 2016 at 08:05:20 UTC, Mike Parker wrote:
> On Wednesday, 20 July 2016 at 08:02:07 UTC, Mike Parker wrote:
>> On Wednesday, 20 July 2016 at 07:49:38 UTC, celavek wrote:
>
>> If you are absolutely, 100% certain that you are dealing with ASCII, you can do this:
>>
>
> And I forgot to add:
>
> Otherwise, you'll want to convert to dchar[] (probably via std.utf.toUTF32) and pass that along instead.

Actually, std.conv.to might be better, since toUTF32 returns dstring:

auto dcharArray = to!(dchar[])(charArray);
July 20, 2016
On Wednesday, 20 July 2016 at 08:02:07 UTC, Mike Parker wrote:
>
> If you are absolutely, 100% certain that you are dealing with ASCII, you can do this:
>
> ```
> import std.string : representation;
> randomShuffle(charArray.representation);
>
> That will give you a ubyte[] for char[] and a ushort[] for wchar[].
>
> [1] https://dlang.org/phobos/std_random.html#.randomShuffle
> [2] https://dlang.org/phobos/std_range_primitives.html#isRandomAccessRange

Ahhh! That again. I was thinking about using the representation. I should take a deeper
look at the documentation.

As far as my current understanding goes the shuffle will be done in place.
If I use the "representation" would that still hold, that is will I be able
to use the same char[] but in the shuffled form? (of course I will test that)

Thank you
July 20, 2016
On Wednesday, 20 July 2016 at 08:18:55 UTC, celavek wrote:

>
> As far as my current understanding goes the shuffle will be done in place.
> If I use the "representation" would that still hold, that is will I be able
> to use the same char[] but in the shuffled form? (of course I will test that)

representation does not allocate any new memory. It points to the same memory, same data. If we think of D arrays as something like this:

struct Array(T) {
    size_t len;
    T* ptr;
}

Then representation is doing this:

Array original;
Array representation(original.len, original.ptr);

So, yes, the char data will still be shuffled in place. All you're doing is getting a ubyte view onto it so that it can be treated as a range.
July 20, 2016
On Wednesday, 20 July 2016 at 08:30:37 UTC, Mike Parker wrote:

>
> representation does not allocate any new memory. It points to the same memory, same data. If we think of D arrays as something like this:
>
> struct Array(T) {
>     size_t len;
>     T* ptr;
> }
>
> Then representation is doing this:
>
> Array original;
> Array representation(original.len, original.ptr);
>
> So, yes, the char data will still be shuffled in place. All you're doing is getting a ubyte view onto it so that it can be treated as a range.

Thank you for the very useful information. I really appreciate taking the time to explain
these, maybe trivial, things to me.

I confirmed the behavior with a test. working as expected.

July 20, 2016
On Wednesday, 20 July 2016 at 08:02:07 UTC, Mike Parker wrote:
> You can then go to the documentation for std.range.primitives.isRandomAccessRange [2], where you'll find the following:
>
> "Although char[] and wchar[] (as well as their qualified versions including string and wstring) are arrays, isRandomAccessRange yields false for them because they use variable-length encodings (UTF-8 and UTF-16 respectively). These types are bidirectional ranges only."

There's also the shuffle module in mach.range which doesn't do any auto-decoding: https://github.com/pineapplemachine/mach.d/blob/master/mach/range/random/shuffle.d
July 20, 2016
On Wednesday, 20 July 2016 at 10:40:04 UTC, pineapple wrote:
> On Wednesday, 20 July 2016 at 08:02:07 UTC, Mike Parker wrote:
>> You can then go to the documentation for std.range.primitives.isRandomAccessRange [2], where you'll find the following:
>>
>> "Although char[] and wchar[] (as well as their qualified versions including string and wstring) are arrays, isRandomAccessRange yields false for them because they use variable-length encodings (UTF-8 and UTF-16 respectively). These types are bidirectional ranges only."
>
> There's also the shuffle module in mach.range which doesn't do any auto-decoding: https://github.com/pineapplemachine/mach.d/blob/master/mach/range/random/shuffle.d

There is no auto-decoding going on here, as char[] and wchar[] are rejected outright since they are not considered random access ranges.
July 20, 2016
On Wednesday, 20 July 2016 at 10:40:04 UTC, pineapple wrote:

>
> There's also the shuffle module in mach.range which doesn't do any auto-decoding: https://github.com/pineapplemachine/mach.d/blob/master/mach/range/random/shuffle.d

Interesting project. Thanks for the link.

« First   ‹ Prev
1 2 3