10
\$\begingroup\$

Design a random number generator where the i th number has i% chance of occurring for all 0 < i < 14. 0 should have exactly 9% chance of occurring. The seed for the generator should be the system time. You cannot use a pre-defined function for random number generation.

Basically 1 has 1% chance of occurring, 2 has 2% chance and so on up to 13 having 13% chance of occurring. This is code-golf, so the shortest code wins.

\$\endgroup\$
  • 7
    \$\begingroup\$ What about the other 9% chance? \$\endgroup\$ – LegionMammal978 Nov 1 '15 at 13:38
  • \$\begingroup\$ @LegionMammal978 I already specified. It should print 0. \$\endgroup\$ – ghosts_in_the_code Nov 1 '15 at 14:10
  • \$\begingroup\$ Yes, it's fine now. What was the problem earlier? \$\endgroup\$ – ghosts_in_the_code Nov 1 '15 at 14:12
  • \$\begingroup\$ @ghosts_in_the_code The < from the inequality and the > from the quote block were forming an HTML tag. \$\endgroup\$ – Martin Ender Nov 1 '15 at 14:13
  • 2
    \$\begingroup\$ Is a resolution of seconds OK? \$\endgroup\$ – xnor Nov 1 '15 at 18:47

11 Answers 11

13
\$\begingroup\$

CJam, 14 bytes

E,_T9t\]ze~es=

Test it here.

Explanation

E,   e# Push [0 1 2 ... 12 13].
_    e# Make a copy.
T9t\ e# Set the first element to 9. Swap with the original range.
]z   e# Wrap them in an array and transpose to get [[9 0] [1 1] [2 2] ... [13 13].
e~   e# Run-length decode to get `[0 0 0 0 0 0 0 0 0 1 2 2 3 3 3 ... 13 13 ... 13 13].
es=  e# Use the current timestamp as a cyclic index into this array.
\$\endgroup\$
  • \$\begingroup\$ Umm, why not mR? \$\endgroup\$ – Optimizer Nov 1 '15 at 18:40
  • 1
    \$\begingroup\$ @Optimizer "The seed for the generator should be the system time. You cannot use a pre-defined function for random number generation." \$\endgroup\$ – Martin Ender Nov 1 '15 at 18:40
  • \$\begingroup\$ Ah, missed that part. \$\endgroup\$ – Optimizer Nov 1 '15 at 18:41
7
\$\begingroup\$

Python 2, 54

import time
print((time.time()*1e4%800+1)**.5+1)//2%14

The expression f(t) = ((8*t+1)**.5+1)//2 transforms a uniform distribution to a triangular integer distribution by mapping the intervals

[0,1)  --> 1
[1,3)  --> 2
[3,6)  --> 3
[6,10) --> 4
...

We convert the millisecond digits of the time to a uniform float from 0 to 100 by doing time.time()*1e4%100. Actually, we do %800 to replace multiplying by 8 in the conversion step. At the end, 14's are converted to 0's by doing %14.

\$\endgroup\$
4
\$\begingroup\$

Pyth - 14 bytes

@+mZ9smRd14.d8

Generates array with the specified distribution, then pick a random one.

Try it online here.

\$\endgroup\$
4
\$\begingroup\$

Dyalog APL, 20 bytes

⊃(⌊.1×⊃⌽⎕TS)↓(/⍨⍳13)

⍳13 integers 1 though 13
(/⍨) replicate by itself, e.g. /⍨3 is 3 3 3 and /⍨2 3 is 2 2 3 3 3
n … drop n elements (leaves empty list if n > length of list)
⎕TS system time stamp e.g. 2015 11 1 13 28 56 834
⊃⌽ last element, i.e. current millisecond 0–999
⌊.1× multiply with 0.1 and round down
first element, gives 0 if if data is empty

\$\endgroup\$
3
\$\begingroup\$

Processing 3, 65 55 74 bytes

long i=0,c=8,r=System.nanoTime()%100;for(;r>c;i++,c+=i);print(i);

Get a random number from 0 to 99 (inclusive). If number is 0-8, print 0, if it is 9 print 1, if 10-11 print 2, if 12-14 print 3, etc...

No one noticed it, but the problem with the old code is that millis() returns the amount of time the application has been running, which would give very similar numbers on subsequent runs of the program. At least now we have nano precision!

\$\endgroup\$
2
\$\begingroup\$

PHP, 50 bytes

<?for($t=microtime()*100;0<=$t-=++$i;)?><?=$i%14;
  • microtime returns the time as a string like "0.04993000 1446409253", when I multiply this by 100, PHP coerces the string into 0.04993000, result 4.993000. So $t is initialized with a "random" number in [0,100)
  • We subtract 1, 2, 3, ... from $t until it reaches 0
  • The result is the last subtracted number, modulo 14
\$\endgroup\$
  • \$\begingroup\$ You can actually write ;echo instead of ?><?=, for the same byte count. But nicely done! \$\endgroup\$ – Ismael Miguel Nov 2 '15 at 10:45
1
\$\begingroup\$

Python3, 86 Bytes

straight forward:

import time;print(sum([[i]*i for i in range(1,14)],[0]*9)[int(str(time.time())[-2:])])
\$\endgroup\$
1
\$\begingroup\$

J - 28 char

This one was silly.

{:({:1e3*6!:0'')$100{.#~i.14

6!:0'' is the current Y M D h m s time as a 6-item list, where milliseconds are represented as fractions on the seconds—to get at them, we have to no choice but to multiply the seconds ({:) by 1e3. Meanwhile, #~i.14 is a list of zero 0s, one 1, two 2s, and so on through to thirteen 13s, and we pad that out to 100 items with 100{..

J doesn't have cyclic indexing, so it might be tempting to take the milliseconds modulo 100 before indexing the big list. However, we can save two characters by using $ to instead cyclically extend the 100-item list to however many milliseconds we get (anywhere from 0 to 60999) and take the last entry then.

Not that a 60000 element list is a whole lot of memory used or anything, it just feels like overkill :P

\$\endgroup\$
1
\$\begingroup\$

JavaScript (ES6) 116

This is an adaptation of a simple seeded RNG that I have used instead of the standard RNG of javascript that cannot be seeded (and so is not repeateble)

R=(s=~new Date,p=[],i=0,j=9)=>{
while(p.push(i)<100)--j?0:j=++i;
return _=>(s=(1+Math.sin(s))*1e5,p[100*(s-~~s)|0])
};

// test

var rnd=R()

t=[0,0,0,0,0,0,0,0,0,0,0,0,0,0];
rgb='000,444,666,888,aaa,ddd,f0f,ff0,0ff,0ff,0f0,00f,f00,fff'.split`,`
.map(v=>(v=parseInt(v,16),[(v&15)*17,(v>>4&15)*17,(v>>8)*17]))

cnt=400*300
//for (i=0;i<cnt;i++)t[rnd()]++;

ctx = C.getContext("2d");
img=ctx.getImageData(0, 0, 400, 300)
for(p=0,y=0;y<300;y++)for(x=0;x<400;x++)
  v=rnd(),t[v]++,
  img.data[p++]=rgb[v][0],img.data[p++]=rgb[v][1],
  img.data[p++]=rgb[v][2],img.data[p++]=255
ctx.putImageData(img, 0, 0)

o=''
for(i=0;i<14;i++)
  t[i]/=cnt, o+=`<p><i>${i}</i><b style="width:${t[i]*300}%">,</b>${(t[i]*100).toFixed(2)}%</p>`;
G.innerHTML=o
#G { width: 400px; font-size: 12px; border: 1px solid #000;  }
p { margin: 0}
b { display: inline-block; font-size:80%; background: #08c; margin: 2px }
i { display: inline-block; width: 20px; text-align: right; padding: 0 4px }
#C { width: 400px; height: 300px; }
<div id=G></div>
<canvas id=C></canvas>

\$\endgroup\$
  • \$\begingroup\$ I really love how you prove that the returned value is really close to the requirements. Nicely done! +10 on that canvas! \$\endgroup\$ – Ismael Miguel Nov 2 '15 at 10:47
0
\$\begingroup\$

TI-BASIC, 18 bytes

real(int(.5+2√(-4+50fPart(sub(getTime

100fPart(sub(getTime gets the random residue between 0 and 99. The (n-1)th triangular number is equal to (N^2+N)/2, so the inverse is equal to √(2y+1)-.5. Floor this after adjusting downwards by 9, and we have the result

The only problem is that for residues less than 8, we get an imaginary square root. So we take the real part to have the program output 0 instead.

\$\endgroup\$
0
\$\begingroup\$

Perl 5, 51 bytes

50 bytes + 1 for -E instead of -e:

@_=(0)x 9;push@_,($_)x$_ for 0..13;say$_[time%100]
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.