introduction
Dans ce défi, votre tâche consiste à implémenter une collection de fonctions simples qui forment ensemble une mini-bibliothèque utilisable pour des distributions de probabilités simples. Pour prendre en charge certains des langages les plus ésotériques que les gens aiment utiliser ici, les implémentations suivantes sont acceptables:
- Un extrait de code définissant une collection de fonctions nommées (ou équivalents les plus proches).
- Collection d'expressions évaluant des fonctions nommées ou anonymes (ou leurs équivalents les plus proches).
- Expression unique qui évalue plusieurs fonctions nommées ou anonymes (ou équivalents les plus proches).
- Une collection de programmes indépendants qui prennent les entrées de la ligne de commande, STDIN ou l'équivalent le plus proche, et la sortie vers STDOUT ou l'équivalent le plus proche.
Les fonctions
Vous devez implémenter les fonctions suivantes, en utilisant des noms plus courts si vous le souhaitez.
uniform
prend en entrée deux nombres à virgule flottantea
etb
, et renvoie la distribution uniforme[a,b]
. Vous pouvez supposer celaa < b
; l'affairea ≥ b
n'est pas définie.blend
prend en entrée trois distributions de probabilitéP
,Q
etR
. Il renvoie une distribution de probabilitéS
, qui tire des valeursx
,y
etz
deP
,Q
etR
, respectivement, et produity
six ≥ 0
, etz
six < 0
.over
prend en entrée un nombre à virgule flottantef
et une distribution de probabilitéP
, et retourne la probabilité quix ≥ f
vaut pour un nombre aléatoirex
tiré deP
.
Pour référence, over
peut être défini comme suit (en pseudocode):
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)
Vous pouvez supposer que toutes les distributions de probabilité données à over
sont construites à l'aide de uniform
et blend
, et que la seule chose qu'un utilisateur va faire avec une distribution de probabilité est de l'alimenter en blend
ou over
. Vous pouvez utiliser n'importe quel type de données pratique pour représenter les distributions: listes de nombres, chaînes, objets personnalisés, etc. La seule chose importante est que l'API fonctionne correctement. De plus, votre implémentation doit être déterministe, dans le sens de toujours renvoyer la même sortie pour les mêmes entrées.
Cas de test
Vos valeurs de sortie doivent être correctes à au moins deux chiffres après la virgule décimale sur ces cas de test.
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
Réponses:
CJam, 58 octets
Ce sont des opérateurs postfix qui travaillent sur la pile:
2.0 1.0 3.0 U O
isover(2, uniform(1, 3))
.Nombre de points
{[\]}
est la fonction elle-même, l':U;
affecte au nomU
et l'affiche. Essentiellement, cela ne fait pas partie de la fonction, donc en comptant la règle de comptage 2, je n'aurais qu'à compter{[\]}
.B
est défini de manière similaire.Cependant,
O
est récursif, et si je ne spécifie pas de nom, il n'y a aucun moyen de recurse. Alors là, je serais enclin à compter la:O;
pièce. Ensuite, mon score est en5+5+48=58
octets au total.Explication
U
saute deux arguments et fait une paire dans l' ordre inverse:a b => [b a]
.B
saute trois arguments et fait une triple rotation afin:a b c => [b c a]
.O
La structure de est la suivante:Le sous-programme Γ gère des distributions uniformes:
Le sous-programme Δ gère les distributions mixtes:
la source
Rubis, 103
Définit trois lambdas,
u
,b
eto
.u
et ilb
suffit de créer des tableaux à deux et trois éléments respectivement.o
suppose qu'un tableau à deux éléments est une distribution uniforme et un tableau à trois éléments est un mélange de trois distributions. Dans ce dernier cas, il s'appelle récursivement.la source
MATLAB, 73
Temps pour une petite "programmation fonctionnelle" dans MATLAB. Ce sont 3 fonctions anonymes. Uniform et blend sont appelés de la même manière que les exemples, mais
over
les arguments doivent être échangés. Je n'ai pas vraiment besoin d'unover
depuis les deux premières fonctions de retour, mais comme une formalitéfeval
est une fonction qui peut appeler une fonction.Maintenant, le système d'analyse et d'évaluation de MATLAB est pour le moins un peu bancal. Il ne vous permet pas d'appeler directement une fonction renvoyée par une fonction. Au lieu de cela, il faut d'abord enregistrer le résultat dans une variable. Le 4ème exemple pourrait se faire comme suit:
Cependant, il est possible de contourner ce problème en utilisant
feval
pour appeler toutes les fonctions. Si les définitions suivantes sont utilisées, les exemples peuvent être évalués exactement tels qu'ils sont écrits.la source
Mathematica,
129116 octetsu
,b
Eto
sontuniform
,blend
etover
respectively.Wrapper les fonctions standard. Remplacez le\uF3D2
s par le caractère à 3 octets. Renvoie simplement0
et1
pour les cas 1, 4 et 7.la source
Python, 146 octets
Même stratégie que la réponse Ruby de l'histocrate, mais en Python. Faire une récursivité sans Z-combinateur (ce qui serait coûteux),
x
ety
sont définis comme des fonctions d'assistance qui évaluent lesover
tuples d'argument de 2 et 3 longueurs (uniform
et lesblend
arguments, respectivement).Cas de test sur ideone
la source
Matlab, 104 octets
J'espère que cela est toujours valable, car cela ne fonctionne que pour les distributions avec prise en charge dans [-10,10] qui est l'exigence pour les langues qui ne prennent pas en charge la virgule flottante. Le vecteur de support et la précision peuvent être facilement ajustés en modifiant simplement les nombres correspondants.
u,o,b
est pouruniform,blend,over
. Le pdf est simplement représenté comme un vecteur discret. Je pense que cette approche peut facilement être transférée dans d'autres langues.Vous pouvez les tester si vous définissez d'abord ces fonctions, puis collez simplement ce code:
la source
X
etD
parMIN_FLOAT
etMAX_FLOAT
(ou quel que soit l'appeler Matlab), alors c'est une approche valide.realmax
/realmin
, vous pourriez même créer un vecteur qui va à travers tous les nombres à virgule flottante si vous avez suffisamment de mémoire.