On 02/18/2012 02:52 AM, Alf P. Steinbach wrote:
On 18.02.2012 02:39, H. S. Teoh wrote:
// Outputs a randomly selected line from standard input with equal
// likelihood.
import std.random;
import std.stdio;

void main() {
    auto n = 0;
    string choice;
    foreach (line; stdin.byLine()) {
        n++;
        if (uniform(0,n) == 0)
            choice = line.idup;
    }
    writeln(choice);
}


P.S. Proof that the probability any line is selected is exactly 1/n
(where n is the total number of lines read) is left as an exercise for
the reader. ;-)

Assuming that by "any" you mean "any particular", you would have to read
all the lines first. Otherwise, if the code selects the first line with
probability 1/K, then I can just input some other number of lines.


P.S.S. The .idup is a bit ugly, but necessary, since apparently byLine()
calls readln() with a static buffer, so choice will be silently
overwritten if the .idup is omitted.

If the .idup is omitted the code does not compile. It does not silently misbehave. That is why we have a const system.


That sounds ominous. One should never have to be aware of low level
details in order to do simple string assignment or initialization, when
the source already is a string.

The source is not a string, it is a char[].

Does one really have to do that in D?


Cheers & hth.,

- Alf

File.byLine re-uses the buffer in order to be more efficient. This appears in the documentation, and the buffer is typed appropriately.

Reply via email to