"I" tem "i" chance de ocorrer

10

Projete um gerador de números aleatórios em que o iésimo número tenha i% de chance de ocorrer para todos os 0 <i <14. 0 deve ter exatamente 9% de chance de ocorrer. A semente do gerador deve ser a hora do sistema. Você não pode usar uma função predefinida para geração de números aleatórios.

Basicamente, 1 tem 1% de chance de ocorrer, 2 tem 2% de chance e assim por diante, até 13, 13% de chance de ocorrer. Isso é código-golfe, então o código mais curto vence.

ghosts_in_the_code
fonte
7
E quanto aos outros 9% de chance?
precisa
@ LegionMammal978 eu já especifiquei. Deve imprimir 0.
ghosts_in_the_code
Sim, está tudo bem agora. Qual foi o problema anterior?
precisa saber é o seguinte
@ghosts_in_the_code Os valores <da desigualdade e do >bloco de cotação estavam formando uma tag HTML.
Martin Ender
2
A resolução de segundos está OK?
Xnor

Respostas:

13

CJam, 14 bytes

E,_T9t\]ze~es=

Teste aqui.

Explicação

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
fonte
Umm, por que não mR?
Optimizer
11
@Optimizer "A semente do gerador deve ser a hora do sistema. Você não pode usar uma função predefinida para geração de números aleatórios."
Martin Ender
Ah, perdi essa parte.
Optimizer
7

Python 2, 54

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

A expressão f(t) = ((8*t+1)**.5+1)//2transforma uma distribuição uniforme em uma distribuição inteira triangular, mapeando os intervalos

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

Convertemos os dígitos de milissegundos do tempo em um flutuador uniforme de 0 a 100, fazendo isso time.time()*1e4%100. Na verdade, %800substituímos a multiplicação por 8 na etapa de conversão. No final, 14 são convertidos em 0 fazendo %14.

xnor
fonte
4

Pitão - 14 bytes

@+mZ9smRd14.d8

Gera matriz com a distribuição especificada e depois escolhe uma aleatória.

Experimente online aqui .

Maltysen
fonte
4

Dyalog APL , 20 bytes

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

⍳13números inteiros 1 a 13
(/⍨)replicam por si só, por exemplo, /⍨3são 3 3 3e /⍨2 3são 2 2 3 3 3
n … drop n elementos (deixa a lista vazia se n > comprimento da lista)
⎕TSregistro de data e hora do sistema, por exemplo, 2015 11 1 13 28 56 834
⊃⌽último elemento, ou seja, o milissegundo atual 0–999 se
⌊.1×multiplica com 0,1 e arredondar para baixo o
primeiro elemento, fornece 0 se os dados estiverem vazios

Adão
fonte
3

Processando 3, 65 55 74 bytes

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

Obtenha um número aleatório de 0 a 99 (inclusive). Se o número for 0-8, imprima 0, se for 9, imprima 1, se 10-11, imprima 2, se 12-14, imprima 3, etc ...

Ninguém percebeu, mas o problema com o código antigo é que millis () retorna a quantidade de tempo que o aplicativo está sendo executado, o que daria números muito semelhantes nas execuções subseqüentes do programa. Pelo menos agora temos nano precisão!

geokavel
fonte
2

PHP, 50 bytes

<?for($t=microtime()*100;0<=$t-=++$i;)?><?=$i%14;
  • microtimeretorna o tempo como uma sequência como "0,04993000 1446409253", quando multiplico por 100, o PHP coage a sequência em 0,04993000, resultado 4,993000. Então, $té inicializado com um número "aleatório" em[0,100)
  • Subtraímos 1, 2, 3, ... de $taté atingir 0
  • O resultado é o último número subtraído, módulo 14
Fabian Schmengler
fonte
Você pode realmente escrever em ;echovez de ?><?=, para a mesma contagem de bytes. Mas bem feito!
Ismael Miguel
1

Python3, 86 bytes

direto:

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

J - 28 car

Este foi bobo.

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

6!:0''é o Y M D h m shorário atual como uma lista de 6 itens, em que milissegundos são representados como frações nos segundos - para alcançá-los, não temos outra opção senão multiplicar os segundos ( {:) por 1e3. Enquanto isso, #~i.14é uma lista de zero 0s, um 1, dois 2s e assim por diante até treze 13s, e somamos isso a 100 itens 100{..

J não possui indexação cíclica, portanto, pode ser tentador usar o módulo 100 de milissegundos antes de indexar a grande lista. No entanto, podemos salvar dois caracteres usando, $em vez disso, estender ciclicamente a lista de 100 itens para o número de milissegundos que conseguirmos (de 0 a 60999 ) e fazer a última entrada.

Não que uma lista de 60000 elementos seja usada com muita memória ou algo assim, apenas parece um exagero: P

algoritmshark
fonte
1

JavaScript (ES6) 116

Esta é uma adaptação de um RNG semeado simples que eu usei em vez do RNG padrão de javascript que não pode ser semeado (e, portanto, não é reproduzível)

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
fonte
Eu realmente amo como você prova que o valor retornado está muito próximo dos requisitos. Bem feito! +10 nessa tela!
Ismael Miguel
0

TI-BASIC, 18 bytes

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

100fPart(sub(getTimeobtém o resíduo aleatório entre 0 e 99. O número triangular (n-1) é igual a (N^2+N)/2, então o inverso é igual a √(2y+1)-.5. Coloque isso depois de ajustar para baixo em 9, e temos o resultado

O único problema é que, para resíduos menores que 8, obtemos uma raiz quadrada imaginária. Portanto, pegamos a parte real para obter o programa como saída 0.

lirtosiast
fonte
0

Perl 5, 51 bytes

50 bytes + 1 para em -Evez de -e:

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