10
3
Create a function that will output a set of distinct random numbers drawn from a range. The order of the elements in the set is unimportant (they can even be sorted), but it must be possible for the contents of the set to be different each time the function is called.
The function will receive 3 parameters in whatever order you want:
- Count of numbers in output set
- Lower limit (inclusive)
- Upper limit (inclusive)
Assume all numbers are integers in the range 0 (inclusive) to 231 (exclusive). The output can be passed back any way you want (write to console, as an array, etc.)
Judging
Criteria includes the 3 R's
- Run-time - tested on a quad-core Windows 7 machine with whatever compiler is freely or easily available (provide a link if necessary)
- Robustness - does the function handle corner cases or will it fall into an infinite loop or produce invalid results - an exception or error on invalid input is valid
- Randomness - it should produce random results that are not easily predictable with a random distribution. Using the built in random number generator is fine. But there should be no obvious biases or obvious predictable patterns. Needs to be better than that random number generator used by the Accounting Department in Dilbert
If it is robust and random then it comes down to run-time. Failing to be robust or random greatly hurts its standings.
@IlmariKaronen: RE: Randomness: I've seen implementations before that were woefully unrandom. Either they had a heavy bias, or lacked the ability to produce different results on consecutive runs. So we are not talking cryptographic level randomness, but more random than the Accounting Department's random number generator in Dilbert.
– Jim McKeeth – 2012-01-28T05:08:53.003If the request is to pick 5 distinct values in the range of (0..3) - shall we sanitize against such unfulfillable requests? – user unknown – 2012-01-31T03:12:06.690
And since it is a performance hack, the question is important, what type of test is performed. For example, if you have to pick 10,000 elements of 10,001, it would be fast to shuffle the 10,001 and pick the first 10,000. But if you just have to pick 1,000 of 100,000 you can put randomly chosen elements into a set, until it is filled with 1,000 elements (which is my solution so far), but this will be slow, if you have most of the elements of a very big collection. – user unknown – 2012-01-31T03:17:27.507
Is the output supposed to pass something like the DIEHARD or TestU01 tests, or how will you judge its randomness? Oh, and should the code run in 32 or 64 bit mode? (That will make a big difference for optimization.)
– Ilmari Karonen – 2012-01-27T06:35:32.803TestU01 is probably a bit harsh, I guess. Does criterion 3 imply a uniform distribution? Also, why the non-repeating requirement? That's not particularly random, then. – Joey – 2012-01-27T08:36:17.363
@Joey, sure it is. It's random sampling without replacement. As long as no-one claims that the different positions in the list are independent random variables there's no problem. – Peter Taylor – 2012-01-27T11:07:33.723
Ah, indeed. But I'm not sure whether there are well-established libraries and tools for measuring randomness of sampling :-) – Joey – 2012-01-27T11:12:22.460