Introdução
Nesse desafio, sua tarefa é implementar uma coleção de funções simples que, juntas, formam uma mini-biblioteca utilizável para distribuições simples de probabilidade. Para acomodar algumas das línguas mais esotéricas que as pessoas gostam de usar aqui, as seguintes implementações são aceitáveis:
- Um trecho de código que define uma coleção de funções nomeadas (ou equivalentes mais próximos).
- Uma coleção de expressões que avaliam funções nomeadas ou anônimas (ou equivalentes mais próximos).
- Uma única expressão que avalia várias funções nomeadas ou anônimas (ou equivalentes mais próximos).
- Uma coleção de programas independentes que recebem entradas da linha de comando, STDIN ou equivalente mais próximo e são enviadas para STDOUT ou equivalente mais próximo.
As funções
Você deve implementar as seguintes funções, usando nomes mais curtos, se desejar.
uniform
toma como entrada dois números de ponto flutuantea
eb
, e retorna a distribuição uniforme no[a,b]
. Você pode assumir issoa < b
; o casoa ≥ b
é indefinido.blend
toma como entradas três distribuições de probabilidadeP
,Q
eR
. Retorna uma distribuição de probabilidadeS
, que desenha valoresx
,y
ez
deP
,Q
eR
, respectivamente, e produzy
sex ≥ 0
ez
sex < 0
.over
toma como entrada um número de ponto flutuantef
e uma distribuição de probabilidadeP
e retorna a probabilidade quex ≥ f
vale para um número aleatóriox
retiradoP
.
Para referência, over
pode ser definido da seguinte forma (em pseudocódigo):
over(f, uniform(a, b)):
if f <= a: return 1.0
else if f >= b: return 0.0
else: return (b - f)/(b - a)
over(f, blend(P, Q, R)):
p = over(0.0, P)
return p*over(f, Q) + (1-p)*over(f, R)
Você pode assumir que todas as distribuições de probabilidade atribuídas over
são construídas usando uniform
e blend
, e que a única coisa que um usuário fará com uma distribuição de probabilidade é alimentá-lo com blend
ou over
. Você pode usar qualquer tipo de dados conveniente para representar as distribuições: listas de números, seqüências de caracteres, objetos personalizados etc. A única coisa importante é que a API funcione corretamente. Além disso, sua implementação deve ser determinística, no sentido de sempre retornar a mesma saída para as mesmas entradas.
Casos de teste
Seus valores de saída devem estar corretos para pelo menos dois dígitos após o ponto decimal nesses casos de teste.
over(4.356, uniform(-4.873, 2.441)) -> 0.0
over(2.226, uniform(-1.922, 2.664)) -> 0.09550806803314438
over(-4.353, uniform(-7.929, -0.823)) -> 0.49676329862088375
over(-2.491, uniform(-0.340, 6.453)) -> 1.0
over(0.738, blend(uniform(-5.233, 3.384), uniform(2.767, 8.329), uniform(-2.769, 6.497))) -> 0.7701533851999125
over(-3.577, blend(uniform(-3.159, 0.070), blend(blend(uniform(-4.996, 4.851), uniform(-7.516, 1.455), uniform(-0.931, 7.292)), blend(uniform(-5.437, -0.738), uniform(-8.272, -2.316), uniform(-3.225, 1.201)), uniform(3.097, 6.792)), uniform(-8.215, 0.817))) -> 0.4976245638164541
over(3.243, blend(blend(uniform(-4.909, 2.003), uniform(-4.158, 4.622), blend(uniform(0.572, 5.874), uniform(-0.573, 4.716), blend(uniform(-5.279, 3.702), uniform(-6.564, 1.373), uniform(-6.585, 2.802)))), uniform(-3.148, 2.015), blend(uniform(-6.235, -5.629), uniform(-4.647, -1.056), uniform(-0.384, 2.050)))) -> 0.0
over(-3.020, blend(blend(uniform(-0.080, 6.148), blend(uniform(1.691, 6.439), uniform(-7.086, 2.158), uniform(3.423, 6.773)), uniform(-1.780, 2.381)), blend(uniform(-1.754, 1.943), uniform(-0.046, 6.327), blend(uniform(-6.667, 2.543), uniform(0.656, 7.903), blend(uniform(-8.673, 3.639), uniform(-7.606, 1.435), uniform(-5.138, -2.409)))), uniform(-8.008, -0.317))) -> 0.4487803553043079
fonte
Respostas:
CJam, 58 bytes
Estes são operadores postfix que trabalham na pilha:
2.0 1.0 3.0 U O
isover(2, uniform(1, 3))
.Contagem de pontuação
{[\]}
é a própria função, a:U;
atribui ao nomeU
e a exibe. Essencialmente, isso não faz parte da função; portanto, pela regra de contagem de pontuação 2, eu precisaria apenas contar{[\]}
.B
é definido da mesma forma.No entanto,
O
é recursivo e, se eu não especificar um nome, não há como recursar. Então aqui, eu estaria inclinado a contar a:O;
parte. Então minha pontuação é de5+5+48=58
bytes no total.Explicação
U
estala dois argumentos e faz com que um par em ordem inversa:a b => [b a]
.B
estala três argumentos e faz um triplo a fim rodada:a b c => [b c a]
.O
estrutura é a seguinte:O subprograma Γ lida com distribuições uniformes:
O subprograma Δ lida com distribuições combinadas:
fonte
Ruby, 103
Define três lambdas,
u
,b
, eo
.u
eb
apenas crie matrizes de dois e três elementos, respectivamente.o
assume que uma matriz de dois elementos é uma distribuição uniforme e uma de três elementos é uma mistura de três distribuições. No último caso, ele se chama recursivamente.fonte
MATLAB, 73
Hora de um pouco de "programação funcional" no MATLAB. Estas são 3 funções anônimas. Uniforme e mistura são chamados da mesma maneira que os exemplos, mas
over
os argumentos devem ser trocados. Eu realmente não preciso de umaover
desde as duas primeiras funções de retorno, mas como formalidadefeval
é uma função que pode chamar uma função.Agora, o sistema de análise e avaliação do MATLAB é um pouco instável, para dizer o mínimo. Não permite que você chame diretamente uma função retornada de uma função. Em vez disso, é necessário primeiro salvar o resultado em uma variável. O quarto exemplo pode ser feito da seguinte maneira:
No entanto, é possível contornar isso usando
feval
para chamar todas as funções. Se as seguintes definições forem usadas, os exemplos poderão ser avaliados exatamente como estão escritos.fonte
Mathematica,
129116 bytesu
,b
eo
sãouniform
,blend
eover
respectivamente.Wrapper sobre as funções padrão. Substitua os\uF3D2
pelo caractere de 3 bytes. Apenas retorna0
e1
para os casos 1, 4 e 7.fonte
Python, 146 bytes
Mesma estratégia que a resposta Ruby do histocrata, mas em Python. Fazer recursão sem um combinador Z (o que seria caro)
x
ey
são definidas como funções auxiliares que avaliam asover
tuplas de argumento de 2 e 3 comprimentos (uniform
eblend
argumentos, respectivamente).Casos de teste em ideone
fonte
Matlab, 104 bytes
Espero que isso ainda seja válido, pois isso só funciona para distribuições com suporte em [-10,10], que é o requisito para idiomas que não têm suporte a ponto flutuante. O vetor de suporte e a precisão podem ser facilmente ajustados apenas alterando os números correspondentes.
u,o,b
é parauniform,blend,over
. O pdf é apenas representado como um vetor discreto. Eu acho que essa abordagem pode ser facilmente transferida para outros idiomas.Você pode testá-los se definir essas funções primeiro e depois colar este código:
fonte
X
eD
porMIN_FLOAT
eMAX_FLOAT
(ou como o Matlab os chama), essa é uma abordagem válida.realmax
/realmin
, você pode até criar um vetor que atravessa todo o número de ponto flutuante, se tiver memória suficiente.