Wprowadzenie
W tym wyzwaniu Twoim zadaniem jest zaimplementowanie zbioru prostych funkcji, które razem tworzą użyteczną minibibliotekę dla prostych rozkładów prawdopodobieństwa. Aby dostosować się do niektórych bardziej ezoterycznych języków, których ludzie lubią tutaj używać, dopuszczalne są następujące implementacje:
- Fragment kodu definiujący zbiór nazwanych funkcji (lub najbliższych odpowiedników).
- Zbiór wyrażeń, które oceniają na nazwane lub anonimowe funkcje (lub najbliższe odpowiedniki).
- Pojedyncze wyrażenie, które ocenia do kilku nazwanych lub anonimowych funkcji (lub najbliższych odpowiedników).
- Zbiór niezależnych programów, które pobierają dane wejściowe z wiersza poleceń, STDIN lub najbliższego odpowiednika i wysyłają dane do STDOUT lub najbliższego odpowiednika.
Funkcje
Wdrożysz następujące funkcje, w razie potrzeby używając krótszych nazw.
uniform
przyjmuje jako wejście dwóch liczb zmiennoprzecinkowycha
ib
, i zwraca rozkład jednolity na[a,b]
. Możesz założyć, żea < b
; sprawaa ≥ b
jest niezdefiniowana.blend
przyjmuje jako dane wejściowe trzy rozkłady prawdopodobieństwaP
,Q
orazR
. Zwraca rozkład prawdopodobieństwaS
, który opiera się wartośćx
,y
iz
zP
,Q
iR
, odpowiednio, ulegay
, gdyx ≥ 0
iz
jeżelix < 0
.over
przyjmuje jako dane wejściowe liczbę zmiennoprzecinkowąf
i rozkład prawdopodobieństwaP
i zwraca prawdopodobieństwo, które obowiązujex ≥ f
dla losowej liczbyx
wyciągniętej zP
.
W celach informacyjnych over
można zdefiniować w następujący sposób (w pseudokodzie):
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)
Możesz założyć, że wszystkie podane rozkłady prawdopodobieństwa over
są konstruowane przy użyciu uniform
i blend
, i że jedyną rzeczą, którą użytkownik zrobi z rozkładem prawdopodobieństwa, jest karmienie go do blend
lub over
. Możesz użyć dowolnego wygodnego typu danych do przedstawienia dystrybucji: list liczb, ciągów znaków, obiektów niestandardowych itp. Jedyną ważną rzeczą jest to, że interfejs API działa poprawnie. Ponadto twoja implementacja musi być deterministyczna w tym sensie, że zawsze zwraca ten sam wynik dla tych samych danych wejściowych.
Przypadki testowe
Twoje wartości wyjściowe powinny być poprawne do co najmniej dwóch cyfr po przecinku w tych przypadkach testowych.
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