Sellecting randomly from a range

bearophile bearophileHUGS at lycos.com
Mon May 18 02:25:32 PDT 2009


Jesse Phillips:

> import std.algorithm;
> import std.random;
> import std.range;
> import std.stdio;
> 
> string[] list =  ["one", "two", "three", "four", "five"];
> string[] list2 = ["1", "2", "3", "4", "5"];
> 
> void main(string[] args) {
>    auto rnd = new Random(unpredictableSeed);
> 
>    int count = uniform(1, list.length, rnd);
> 
>    string[] result = new string[count*2];
> 
>    fill(result[0..count], take(count, randomCover(list, rnd)));
>    fill(result[count..$], take(count, randomCover(list2, rnd)));
> 
>    writeln(result);
> }

It's essential to compare such code with other ways/languages to produce a similar output:

Something similar in Python:

from random import randint, choice

list1 = ["one", "two", "three", "four", "five"]
list2 = ["1", "2", "3", "4", "5"]
count = randint(1, len(list1))
result = [choice(list1) for _ in xrange(count)]
result.extend(choice(list2) for _ in xrange(count))
print result


In D1 with my dlibs:

import d.string: putr;
import d.random: choice, randInt;
import d.func: table;

void main() {
    string[] list1 = ["one", "two", "three", "four", "five"];
    string[] list2 = ["1", "2", "3", "4", "5"];

    int count = randInt(1, list1.length);
    auto result = table(choice(list1), count) ~
                  table(choice(list2), count);
    putr(result);
}

There are ways to do something similar without array concat too, and to create a lazy result too:

import d.string: putr;
import d.random: choice, randInt;
import d.func: xmap, array, xrange;

void main() {
    string[] list1 = ["one", "two", "three", "four", "five"];
    string[] list2 = ["1", "2", "3", "4", "5"];

    int count = randInt(1, list1.length);
    auto result = xmap((int i){return choice(i < count ? list1 : list2);}, xrange(count*2));
    putr(array(result));
}

Or just:

import d.string: putr;
import d.random: choice, randInt;
import d.func: xmap, array, xrange;

void main() {
    string[] list1 = ["one", "two", "three", "four", "five"];
    string[] list2 = ["1", "2", "3", "4", "5"];

    int count = randInt(1, list1.length);
    auto result = xmap((int i){return choice(list1);}, xrange(count)) ~
                  xmap((int i){return choice(list2);}, xrange(count));
    putr(array(result));
}

I'm waiting for lazy/eager array comps still in D.

Bye,
bearophile


More information about the Digitalmars-d-learn mailing list