"I" hanno "i" possibilità di verificarsi


10

Progettare un generatore di numeri casuali in cui l'i-esimo numero abbia il% di probabilità di verificarsi per tutti 0 <i <14. 0 dovrebbe avere esattamente il 9% di possibilità di verificarsi. Il seme per il generatore dovrebbe essere il tempo di sistema. Non è possibile utilizzare una funzione predefinita per la generazione di numeri casuali.

Fondamentalmente 1 ha una probabilità dell'1% di verificarsi, 2 ha una probabilità del 2% e così via fino a 13 con una probabilità del 13% di verificarsi. Questo è code-golf, quindi vince il codice più corto.


7
E l'altra probabilità del 9%?
LegionMammal978,

@ LegionMammal978 Ho già specificato. Dovrebbe stampare 0.
ghosts_in_the_code

Sì, ora va bene. Qual era il problema prima?
ghosts_in_the_code

@ghosts_in_the_code Il modulo <from the inequality e >from from the quote stavano formando un tag HTML.
Martin Ender,

2
Una risoluzione di secondi è OK?
xnor

Risposte:


13

CJam, 14 byte

E,_T9t\]ze~es=

Provalo qui.

Spiegazione

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.

Umm, perché no mR?
Ottimizzatore

1
@Optimizer "Il seme per il generatore dovrebbe essere l'ora del sistema. Non è possibile utilizzare una funzione predefinita per la generazione di numeri casuali."
Martin Ender,

Ah, ho perso quella parte.
Ottimizzatore

7

Python 2, 54

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

L'espressione f(t) = ((8*t+1)**.5+1)//2trasforma una distribuzione uniforme in una distribuzione intera triangolare mappando gli intervalli

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

Convertiamo le cifre dei millisecondi del tempo in un galleggiante uniforme da 0 a 100 time.time()*1e4%100. A dire il vero, lo facciamo %800per sostituire moltiplicando per 8 nella fase di conversione. Alla fine, 14 vengono convertiti in 0 facendo %14.



4

Dyalog APL , 20 byte

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

⍳13numeri interi 1 anche se 13
(/⍨... si )replicano da soli, ad esempio /⍨3è 3 3 3ed /⍨2 3è 2 2 3 3 3
n ... rilascia n elementi (lascia la lista vuota se n > lunghezza dell'elenco)
⎕TStimestamp di sistema, ad esempio 2015 11 1 13 28 56 834
⊃⌽ultimo elemento, ovvero millisecondo corrente 0–999
⌊.1×moltiplicare con 0.1 e arrotondando per
primo il primo elemento, dà 0 se i dati sono vuoti


3

Elaborazione 3, 65 55 74 byte

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

Ottieni un numero casuale da 0 a 99 (incluso). Se il numero è 0-8, stampa 0, se è 9 stampa 1, se 10-11 stampa 2, se 12-14 stampa 3, ecc ...

Nessuno l'ha notato, ma il problema con il vecchio codice è che millis () restituisce il tempo in cui l'applicazione è stata in esecuzione, il che darebbe numeri molto simili nelle successive esecuzioni del programma. Almeno ora abbiamo nano precisione!


2

PHP, 50 byte

<?for($t=microtime()*100;0<=$t-=++$i;)?><?=$i%14;
  • microtimerestituisce il tempo come una stringa come "0,04993000 1446409253", quando moltiplico questo per 100, PHP costringe la stringa in 0,04993000, risultato 4.993000. Quindi $tviene inizializzato con un numero "casuale" in[0,100)
  • Sottraiamo 1, 2, 3, ... da $tfino a quando non raggiunge 0
  • Il risultato è l'ultimo numero sottratto, modulo 14

Puoi effettivamente scrivere ;echoinvece di ?><?=, per lo stesso conteggio byte. Ma ben fatto!
Ismael Miguel,

1

Python3, 86 byte

dritto:

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

1

J - 28 caratteri

Questo è stato sciocco.

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

6!:0''è l' Y M D h m sora corrente come un elenco di 6 elementi, in cui i millisecondi sono rappresentati come frazioni sui secondi: per raggiungerli, non dobbiamo fare altro che moltiplicare i secondi ( {:) per 1e3. Nel frattempo, #~i.14è un elenco di zero 0, uno 1, due 2 e così via fino a tredici 13, e lo riempiamo con 100 elementi 100{..

J non ha l'indicizzazione ciclica, quindi potrebbe essere allettante prendere i millisecondi modulo 100 prima di indicizzare la grande lista. Tuttavia, possiamo salvare due caratteri usando $invece di estendere ciclicamente l'elenco di 100 voci a quanti millisecondi otteniamo (ovunque da 0 a 60999 ) e prendere quindi l'ultima voce.

Non che un elenco di 60000 elementi utilizzi molta memoria o altro, sembra semplicemente eccessivo: P


1

JavaScript (ES6) 116

Questo è un adattamento di un semplice RNG con seeding che ho usato al posto del RNG standard di javascript che non può essere eseguito il seeding (e quindi non è ripetibile)

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>


Adoro il modo in cui dimostri che il valore restituito è molto vicino ai requisiti. Ben fatto! +10 su quella tela!
Ismael Miguel,

0

TI-BASIC, 18 byte

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

100fPart(sub(getTimeottiene il residuo casuale compreso tra 0 e 99. Il (n-1) th numero triangolare è uguale a (N^2+N)/2, quindi l'inverso è uguale a √(2y+1)-.5. Metti a terra questo dopo aver regolato verso il basso di 9, e abbiamo il risultato

L'unico problema è che per residui inferiori a 8 otteniamo una radice quadrata immaginaria. Quindi prendiamo la parte reale per avere invece l'uscita 0 del programma.


0

Perl 5, 51 byte

50 byte + 1 per -Eanziché -e:

@_=(0)x 9;push@_,($_)x$_ for 0..13;say$_[time%100]
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.