Introducción
En este desafío, su tarea es implementar una colección de funciones simples que juntas formen una mini biblioteca utilizable para distribuciones de probabilidad simples. Para acomodar algunos de los lenguajes más esotéricos que a la gente le gusta usar aquí, las siguientes implementaciones son aceptables:
- Un fragmento de código que define una colección de funciones con nombre (o equivalentes más cercanos).
- Una colección de expresiones que evalúan funciones nombradas o anónimas (o equivalentes más cercanos).
- Una sola expresión que evalúa varias funciones con nombre o anónimas (o equivalentes más cercanos).
- Una colección de programas independientes que toman entradas de la línea de comando, STDIN o equivalente más cercano, y salen a STDOUT o equivalente más cercano.
Las funciones
Deberá implementar las siguientes funciones, utilizando nombres más cortos si lo desea.
uniform
toma como entrada dos números de punto flotantea
yb
, y devuelve la distribución uniforme sobre[a,b]
. Puedes asumir esoa < b
; El casoa ≥ b
no está definido.blend
toma como entradas tres distribuciones de probabilidadP
,Q
yR
. Devuelve una distribución de probabilidadS
, que extrae valoresx
,y
yz
deP
,Q
yR
, respectivamente, y producey
ifx ≥ 0
, yz
ifx < 0
.over
toma como entrada un número de coma flotantef
y una distribución de probabilidadP
, y devuelve la probabilidad que sex ≥ f
mantiene para un número aleatoriox
extraído deP
.
Como referencia, over
se puede definir de la siguiente manera (en 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)
Puede suponer que todas las distribuciones de probabilidad dadas over
se construyen usando uniform
y blend
, y que lo único que un usuario va a hacer con una distribución de probabilidad es alimentarlo blend
o over
. Puede usar cualquier tipo de datos conveniente para representar las distribuciones: listas de números, cadenas, objetos personalizados, etc. Lo único importante es que la API funciona correctamente. Además, su implementación debe ser determinista, en el sentido de que siempre devuelve la misma salida para las mismas entradas.
Casos de prueba
Sus valores de salida deben ser correctos al menos a dos dígitos después del punto decimal en estos casos de prueba.
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
Respuestas:
CJam, 58 bytes
Estos son operadores de postfix que funcionan en la pila:
2.0 1.0 3.0 U O
isover(2, uniform(1, 3))
.Cuenta de puntaje
{[\]}
es la función en sí, la:U;
asigna al nombreU
y la muestra. Esencialmente, esto no es parte de la función, por lo que al contar la regla 2, solo tendría que contar{[\]}
.B
se define de manera similar.Sin embargo,
O
es recursivo, y si no especifico un nombre, no hay forma de recurrir. Así que aquí, me inclinaría a contar la:O;
parte. Entonces mi puntaje es5+5+48=58
bytes en total.Explicación
U
estallidos dos argumentos y hace un par en orden inverso:a b => [b a]
.B
hace estallar tres argumentos y hace un triple con el fin girada:a b c => [b c a]
.O
La estructura es la siguiente:El subprograma Γ maneja distribuciones uniformes:
El subprograma Δ maneja distribuciones combinadas:
fuente
Ruby, 103
Define tres lambdas,
u
,b
, yo
.u
yb
simplemente cree matrices de dos y tres elementos respectivamente.o
asume que una matriz de dos elementos es una distribución uniforme y una de tres elementos es una combinación de tres distribuciones. En este último caso se llama a sí mismo recursivamente.fuente
MATLAB, 73
Tiempo para una pequeña "programación funcional" en MATLAB. Estas son 3 funciones anónimas. Uniforme y mezcla se llaman de la misma manera que los ejemplos, pero
over
los argumentos deben intercambiarse. Realmente no necesito unaover
desde las dos primeras funciones de retorno, pero como formalidadfeval
es una función que puede llamar a una función.Ahora el sistema de análisis y evaluación de MATLAB es un poco inestable por decir lo menos. No le permite llamar directamente a una función que fue devuelta por una función. En cambio, primero se debe guardar el resultado en una variable. El cuarto ejemplo podría hacerse de la siguiente manera:
Sin embargo, es posible evitar esto utilizando
feval
para llamar a todas las funciones. Si se utilizan las siguientes definiciones, los ejemplos se pueden evaluar exactamente como se escriben.fuente
Mathematica,
129116bytesu
,b
yo
areuniform
,blend
yover
respectivamente. Envolver sobre las funciones estándar. Reemplace la\uF3D2
s con el carácter de 3 bytes. Solo regresa0
y1
para los casos 1, 4 y 7.fuente
Python, 146 bytes
La misma estrategia que la respuesta de Ruby del histocrático, pero en Python. Para hacer recursión sin un combinador Z (lo que sería costoso),
x
yy
se definen como funciones auxiliares que evalúanover
tuplas de argumentos de 2 y 3 longitudes (uniform
yblend
argumentos, respectivamente).Casos de prueba sobre ideona
fuente
Matlab, 104 bytes
Espero que esto siga siendo válido, ya que esto solo funciona para distribuciones con soporte en [-10,10], que es el requisito para los idiomas que no tienen soporte de punto flotante. El vector de soporte y la precisión se pueden ajustar fácilmente simplemente alterando los números correspondientes.
u,o,b
es parauniform,blend,over
. El pdf solo se representa como un vector discreto. Creo que este enfoque se puede transferir fácilmente a otros idiomas.Puede probarlos si define esas funciones primero y luego simplemente pegue este código:
fuente
X
yD
conMIN_FLOAT
yMAX_FLOAT
(o como los llame Matlab), entonces este es un enfoque válido.realmax
/realmin
, incluso podría hacer un vector que atraviese todos los números de coma flotante si tiene suficiente memoria.