JavaScript (ES6), 72 71 70 69 bytes
f=(x,y="")=>x?!y.match(z=Math.random()*10|0)&&y|z?f(x-1,y+z):f(x,y):y
This is a recursive function that takes in the number of digits x. The second parameter y, initially set to the empty string, keeps track of the number as we generate it digit by digit.
First we generate a random digit z with Math.random()*10|0
. Now, we want to check that the y does not contain z, and that y and z are not both 0.
We can calculate the first condition with !y.match(z)
. y.match(z)
returns an array (always truthy) if y contains z, null (falsy) otherwise; the !
converts this to a boolean and inverts it.
The second condition is checked with y|z
. Although y is a string, JS implicitly converts it to an integer when using |
. This is a positive integer if y already contains digits, 0 otherwise. The net result is that y|z
returns 0 iff y is empty and z is 0, or a positive integer otherwise.
If both of these conditions are true, then we append the digit to y, decrement x, and start the process over again. Otherwise, we simply return to the beginning and hope that the next random digit works. When x reaches 0, we simply return the empty string to end the recursion.
Previous version:
f=(x,y)=>x?~y>>(z=Math.random()*10|0)&1&&y|z?z+f(x-1,y|1<<z):f(x,y):""
This is a recursive function that takes in the number of digits. The initially undefined second parameter, y, is a 10-bit lookup table telling us which digits we already have, conveniently stored as an integer.
First we generate a random digit z with Math.random()*10|0
. Now, we want to check that the z'th least significant bit of y is not set, and that y and z are not both 0.
We can calculate the first condition with ~y>>z&1
; invert y, shift it z bits to the right, and take only the least significant bit. This gives 1 if we have not yet generated the digit in question, or 0 otherwise.
The second condition was initially pretty difficult to figure out (I tried using y/z
at first to generate NaN
if they're both 0), but at some point I realized that simply y|z
would do the trick. The result is 0 iff both y and z are 0; a positive integer otherwise.
If both of these conditions are true (~y>>z&1&&y|z
), then we generate the rest of the number and prepend z. The rest of the number is generated by calling the function again with x-1
and y|1<<z
(y, but with the bit at index z set to 1). When x reaches 0, we simply return the empty string to end the recursion.
4
Requiring randomness without specifying a distribution should be avoided.
– flawr – 2017-04-24T19:50:58.237return as an integer, not a string, yes? – Giuseppe – 2017-04-24T20:46:53.087
@Giuseppe generate a random number – mbomb007 – 2017-04-24T20:57:24.063
When you say distinct digits you mean a number like
375
is acceptable but337
is not? – Albert Renshaw – 2017-04-24T23:43:36.387Is pseudo-random allowed? For example I can use current UTC time as a "seed" for a scrambling function so it's not true random because the output can be easily predicted but if you run the program multiple times (seconds apart each time) the output will differ. I guess what I'm asking is, does output have to be RANDOM or just non-static – Albert Renshaw – 2017-04-24T23:50:43.393
4
I think of this every single time someone makes a random number question https://xkcd.com/221/
– Thunda – 2017-04-25T04:56:16.690In chat recently it came up that this challenge is a bit unclear at the lower end. What output is expected for n=0? Is 0 a valid output for n=1? It'd be easiest to set the minimum n to 2 to avoid having to define these corner cases (especially as they may cost quite a few bytes for many of the solutions). – None – 2017-04-25T13:17:51.010
1@ais523 "Give an input 0<n<10 generate a random number with" – cleblanc – 2017-04-25T13:46:29.420
I agree with ais523, though. I'd like to know if we can output zero for
n=1
. My answer currently can. – mbomb007 – 2017-04-25T14:11:40.133@ais523 no you don't have to handle
n=0
. In the Task section it says0<n<10
. no0
isn't a valid output forn=1
since10**(1-1)-1=0
and0
is not greater than0
– Roman Gräf – 2017-04-25T14:45:49.427<joke> Is it acceptabel if the first number is a 0 if it's only 10% of the cases? </joke> – Martijn – 2017-04-26T09:01:43.417