Введение
В этой задаче ваша задача - реализовать набор простых функций, которые вместе образуют полезную мини-библиотеку для простых распределений вероятностей. Чтобы учесть некоторые из более эзотерических языков, которые люди любят использовать здесь, допустимы следующие реализации:
- Фрагмент кода, определяющий коллекцию именованных функций (или ближайших эквивалентов).
- Коллекция выражений, которые оценивают именованные или анонимные функции (или их ближайшие эквиваленты).
- Одно выражение, которое оценивает несколько именованных или анонимных функций (или ближайших эквивалентов).
- Набор независимых программ, которые принимают входные данные из командной строки, STDIN или ближайшего аналога и выводят в STDOUT или ближайший эквивалент.
Функции
Вы должны реализовать следующие функции, используя более короткие имена, если это необходимо.
uniform
принимает в качестве входных данных два числа с плавающей запятойa
иb
и возвращает равномерное распределение[a,b]
. Вы можете предположить, чтоa < b
; делоa ≥ b
не определено.blend
принимает в качестве входных сигналов трех вероятностных распределенийP
,Q
иR
. Он возвращает распределение вероятностейS
, которое рисует значенияx
,y
иz
изP
,Q
иR
, соответственно, и дает,y
еслиx ≥ 0
иz
еслиx < 0
.over
принимает в качестве входных данных число с плавающей запятойf
и распределение вероятностейP
и возвращает вероятность, котораяx ≥ f
имеет место для случайного числа,x
взятого изP
.
Для справки, over
может быть определен следующим образом (в псевдокоде):
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)
Вы можете предположить, что все распределения вероятностей, данные для этого over
, построены с использованием uniform
и blend
, и что единственное, что пользователь собирается делать с распределением вероятностей, это передать его blend
или over
. Вы можете использовать любой удобный тип данных для представления распределений: списки чисел, строки, пользовательские объекты и т. Д. Единственное, что важно, это то, что API работает правильно. Кроме того, ваша реализация должна быть детерминированной, то есть всегда возвращать один и тот же вывод для одних и тех же входных данных.
Контрольные примеры
Ваши выходные значения должны быть правильными, по крайней мере, до двух цифр после десятичной точки в этих тестовых случаях.
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
Ответы:
CJam, 58 байт
Это постфиксные операторы, которые работают в стеке:
2.0 1.0 3.0 U O
естьover(2, uniform(1, 3))
.Счетчик очков
{[\]}
сама функция,:U;
присваивает ей имяU
и выскакивает. По сути, это не является частью функции, поэтому по правилу подсчета очков 2 мне нужно будет только сосчитать{[\]}
.B
определяется аналогично.Тем не менее,
O
это рекурсивно, и если я не укажу имя, нет способа рекурсивно. Так что здесь, я был бы склонен считать:O;
часть. Тогда мой счет в5+5+48=58
байтах.объяснение
U
выскакивает два аргумента и делает пару в обратном порядке:a b => [b a]
.B
выскакивает три аргумента и делает тройным в повернутом порядке:a b c => [b c a]
.O
Структура выглядит следующим образом:Подпрограмма Г обрабатывает равномерные распределения:
Подпрограмма Δ обрабатывает смешанные распределения:
источник
Руби, 103
Определяет три лямбды,
u
,b
, иo
.u
иb
просто создайте двухэлементные и трехэлементные массивы соответственно.o
Предполагается, что двухэлементный массив является равномерным распределением, а трехэлементный массив представляет собой смесь трех распределений. В последнем случае он вызывает себя рекурсивно.источник
МАТЛАБ, 73
Время немного «функционального программирования» в MATLAB. Это 3 анонимные функции. Uniform и blend называются так же, как примеры, но для
over
аргументов их нужно поменять местами. На самом деле мне не нужныover
первые две возвращаемые функции, но формальностьfeval
- это функция, которая может вызывать функцию.Теперь система синтаксического анализа и оценки MATLAB немного не очень удобна, если не сказать больше. Он не позволяет вам напрямую вызывать функцию, которая была возвращена из функции. Вместо этого нужно сначала сохранить результат в переменной. Четвёртый пример можно сделать следующим образом:
Тем не менее, можно обойти это, используя
feval
для вызова всех функций. Если используются следующие определения, то примеры могут быть оценены именно так, как они написаны.источник
Mathematica,
129116 байтовu
,b
иo
естьuniform
,blend
иover
соответственно. Оболочка над стандартными функциями. Замените\uF3D2
s трехбайтовым символом. Просто возвращается0
и1
для случаев 1, 4 и 7.источник
Python, 146 байт
Та же стратегия, что и у гистократского Ruby-ответа, но в Python. Делать рекурсию без Z-комбинатора (что было бы дорого),
x
иy
определяются как вспомогательные функции, которые оцениваютover
для кортежей аргументов 2 и 3 длины (uniform
иblend
аргументы соответственно).Тестовые случаи на ideone
источник
Matlab, 104 байта
Я надеюсь, что это все еще верно, так как это работает только для дистрибутивов с поддержкой в [-10,10], что является требованием для языков, которые не поддерживают плавающую точку. Опорный вектор и точность можно легко отрегулировать, просто изменив соответствующие числа.
u,o,b
дляuniform,blend,over
. PDF просто представлен в виде дискретного вектора. Я думаю, что этот подход можно легко перенести на другие языки.Вы можете проверить их, если сначала определите эти функции, а затем просто вставьте этот код:
источник
X
иD
наMIN_FLOAT
иMAX_FLOAT
(или как их называет Matlab), то это правильный подход.realmax
/realmin
, вы даже можете создать вектор, который проходит через все числа с плавающей запятой, если у вас достаточно памяти.