"i" have "i" chance of occuring

10

1

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.

ghosts_in_the_code

Posted 2015-11-01T13:33:13.570

Reputation: 2 907

7What about the other 9% chance? – LegionMammal978 – 2015-11-01T13:38:36.877

@LegionMammal978 I already specified. It should print 0. – ghosts_in_the_code – 2015-11-01T14:10:10.817

Yes, it's fine now. What was the problem earlier? – ghosts_in_the_code – 2015-11-01T14:12:22.863

@ghosts_in_the_code The < from the inequality and the > from the quote block were forming an HTML tag. – Martin Ender – 2015-11-01T14:13:57.133

2Is a resolution of seconds OK? – xnor – 2015-11-01T18:47:34.340

@xnor What does that mean? – ghosts_in_the_code – 2015-11-02T10:36:53.273

@ghosts_in_the_code That the seed only changes every second (as opposed to every millisecond, say). That is, if the random number generator is run twice within the same second, the results would be identical. – Martin Ender – 2015-11-02T15:03:03.380

@xnor Yes, it is allowed. – ghosts_in_the_code – 2015-11-02T16:28:46.110

Answers

13

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.

Martin Ender

Posted 2015-11-01T13:33:13.570

Reputation: 184 808

Umm, why not mR? – Optimizer – 2015-11-01T18:40:13.323

1@Optimizer "The seed for the generator should be the system time. You cannot use a pre-defined function for random number generation." – Martin Ender – 2015-11-01T18:40:39.500

Ah, missed that part. – Optimizer – 2015-11-01T18:41:23.913

7

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.

xnor

Posted 2015-11-01T13:33:13.570

Reputation: 115 687

4

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

Adám

Posted 2015-11-01T13:33:13.570

Reputation: 37 779

4

Pyth - 14 bytes

@+mZ9smRd14.d8

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

Try it online here.

Maltysen

Posted 2015-11-01T13:33:13.570

Reputation: 25 023

3

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!

geokavel

Posted 2015-11-01T13:33:13.570

Reputation: 6 352

2

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

Fabian Schmengler

Posted 2015-11-01T13:33:13.570

Reputation: 1 972

You can actually write ;echo instead of ?><?=, for the same byte count. But nicely done! – Ismael Miguel – 2015-11-02T10:45:25.890

1

Python3, 86 Bytes

straight forward:

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

ch3ka

Posted 2015-11-01T13:33:13.570

Reputation: 71

1

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>

edc65

Posted 2015-11-01T13:33:13.570

Reputation: 31 086

I really love how you prove that the returned value is really close to the requirements. Nicely done! +10 on that canvas! – Ismael Miguel – 2015-11-02T10:47:04.173

1

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

algorithmshark

Posted 2015-11-01T13:33:13.570

Reputation: 8 144

0

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.

lirtosiast

Posted 2015-11-01T13:33:13.570

Reputation: 20 331

0

Perl 5, 51 bytes

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

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

msh210

Posted 2015-11-01T13:33:13.570

Reputation: 3 094