Você recebe uma função Rand5 (). Essa função retorna números inteiros perfeitamente aleatórios (distribuição igual) entre 1 e 5.
Forneça a função Rand7 (), que usa Rand5 () para produzir números inteiros perfeitamente aleatórios entre 1 e 7.
code-challenge
math
random
Dan McGrath
fonte
fonte
Respostas:
Java - 61 caracteres
Driver de teste para validação:
Resultados
fonte
rand5
. Eu os calculei no Maple usando álgebra matricial simples, mas você pode fazê-lo com lápis e papel em alguns minutos, se quiser. De qualquer forma, o Omar já postou os mesmos números (sem fator de normalização) em um comentário para outra resposta alguns dias antes. (Também ps., Você só pode @ notificar um usuário por comentário, embora o autor da publicação seja sempre notificado em qualquer caso.)Perl - 47 (tinha 52) caracteres
Além disso, uso o operador ternário AND recursão. Melhor dia de todos!
OK, 47 caracteres se você usar mod em vez de div:
fonte
&
sinais para reduzi-lo para 46 caracteres (incluindo o espaço, que coloca sua versão atual em 48).JavaScript, 42
Coisa bônus ES5:
fonte
Ruby - 54 caracteres (baseado na solução Dan McGrath, usando loop)
Ruby - 45 caracteres (mesma solução, usando recursão)
fonte
(x=rand5+5*rand5-5)>7?
.Em Python:
fonte
Em caracteres comuns do Lisp 70:
Os parênteses ocupam mais espaço do que eu gostaria.
fonte
(defun rand7()(setq n(-(+(rand5)(* 5(rand5)))5))(if(> n 7)(rand7)n))
(defun rand7()(if(>(setq n(-(+(rand5)(* 5(rand5)))5))7)(rand7)n))
Em c / c ++ usando amostragem por rejeição
62 caracteres.
fonte
while(x>7)
, de modo que só seria satisfeita por números no intervalo válido.Tradução para PHP, a partir da resposta publicada por Dan McGrath.
67 caracteres.
fonte
R, 34 caracteres
Em R (uma linguagem criada para computação estatística), uma solução deliberadamente trapaceira:
Graças à preguiçosa avaliação dos argumentos, eliminei o ponto-e-vírgula e o aparelho.
A saída acima de 10 ^ 6 replica:
fonte
Rand7=function(){r=Rand5();sample(7)[r]}
Rand7=function(){sample(7)[Rand5()]}
scala,
47, 4059 caracteres:com 2 entradas da rand5:
Multiplico o primeiro-1 por 5 e adiciono o segundo. A maioria dos resultados é ignorada e leva a um novo cálculo. O resultado deve ser uma distribuição igual de valores de 1 a 25, da qual seleciono apenas os 7 primeiros. Eu poderia aceitar os 21 primeiros com a construção de um módulo, mas isso levaria a um código mais longo.
código histórico que falhou, mas não muito obviamente. Agradecemos a Ilmari Karonen por apontar:
Graças a Yoshiteru Takeshita, por essa abordagem de scala-2.8.0 que tornou a 'soma' tão fácil. Minha solução antes:
rand5:
fonte
def rand7=(1 to 7).map(_=>rand5).sum%7+1
C ++
C ++ (109)
Golfe
fonte
Tradução para Javascript, a partir da resposta postada por Dan McGrath.
62 caracteres
fonte
function Rand7(){for(x=8;x>7;x=rand5()+5*rand5()-5);return x}
é um pouco mais curto: PJavaScript, 85
Eu sei que há uma resposta mais curta, mas eu queria mostrar o teste desse quebra-cabeça. Acontece que apenas a resposta de Clyde Lobo usando a amostragem de rejeição de Dan McGrath está correta (entre as respostas do JS).
fonte
С ++
Distribuição de números (1000000 números inteiros):
O número médio de chamadas para Rand5 () por cada número inteiro gerado é de cerca de 2,2 (2 a 10 ou mais).
fonte
Em Java (ou C / C ++, suponho)
usando a fórmula de geração de Alexandru, em 65 caracteres:
usando a fórmula de geração de Dan McGrath, em 60 caracteres
fonte
Clojure - 58 chars
fonte
Python,
5637 charsAnother solution that may be wrong, in Python:
This seems to be too simple, but when I try:
I get a reasonably even distribution (all between 14000 and 14500).
Okay, now as somebody voted for this post: Is this solution indeed correct? I more posted this here to make people criticize it. Well, if it is correct, my golfed version would be:
which comes out to 37 chars.
fonte
Java, 65 chars:
fonte
Python, 70 chars
but completely correct based on the reasoning here.
fonte
Perl, 43 chars, iterative rejection sampling
This gives a warning about
Ambiguous use of -rand5 resolved as -&rand5()
, but works correctly. Prepending an&
also to the secondrand5
call fixes it at the cost of one stroke. (Conversely, the other&
can also be removed ifrand5
has been defined with a()
prototype.)Ps. The following 46-char version is about three times faster:
fonte
Java - 66 chars
Longer than previous routine, but I think this one returns uniformly distributed numbers in less time.
fonte
PostScript (46)
This uses binary token encoding, therefore, here is a hexdump:
To try it out, you can also download it.
Here is the ungolfed and commented code, together with testing code.
fonte
fonte
R (30 characters)
Define rand7:
Because R was written with statistical analysis in mind, this task is trivial, and I use the built-in function
sample
with replacement set to TRUE.Sample output:
fonte
Groovy
example distribution over 35,000 iterations:
Is it bad that it's stateful?
fonte
Mathematica, 30
fonte
How about this?
fonte
/
operator do integer math? What happens to your results if it does decimal, floating-point, or integer math?[2/25, 4/25, 5/25, 5/25, 5/25, 3/25, 1/25]
. Not exactly uniform.Java - 54
Distribution test:
[1000915, 999689, 999169, 998227, 1001653, 1000419, 999928]
Algorithm:
> The numbers are not mutually uncorrelated anymore, but individually perfectly random.
fonte
Ruby (43 bytes)
cemper93's solution ported to Ruby is three bytes shorter ;) (34 bytes)
fonte
C/C++ code the core code has one line only!
The srand7() is the seed of rand7, must call this function before rand7, just like call srand before rand in C.
This is a very good one, because it call rand() only one time, and no loop thing, no expends extra memories.
Let me explain it: consider a integer array with size of 5:
So we got the TABLE, each one of 1-7 appears 5 times in it, and has all 35 numbers, so the probability of each number is 5/35=1/7. And next time,
After enough times, we can get the uniform distribution of 1-7.
So, we can allocate a array to restore the five elements of 1-7 by loop-left-shift, and get one number from array each time by rand5. Instead, we can generate the all seven arrays before, and using them circularly. The code is simple also, has many short codes can do this.
But, we can using the properties of % operation, so the table 1-7 rows is equivalent with (rand5 + i) % 7, that is : a = rand() % 5 + 1 is rand5 in C language, b = gi++ % 7 generates all permutations in table above, and 0 - 6 replace 1 - 7 c = (a + b) % 7 + 1, generates 1 - 7 uniformly. Finally, we got this code:
But, we can not get 6 and 7 at first call, so we need a seed, some like srand for rand in C/C++, to disarrange the permutation for first formal call.
Here is the full code to testing:
fonte
6
or7
by calling it once?int main(){if(rand7()==6) printf("Hello, world!");}
, approximation using loop will print 'Hello, world!' 1 in 7 times, but your code doesn't.