Рысь, не смотри на этот пост, я опасаюсь окончательно пасть в твоих глазах
.Ладно, пусть минусы тоже считаются, но тогда пусть идут по полуторной цене.
Cost = (PositiveKarma + 1.5 * NegativeKarma) / PostCount
А еще мне тут подумалось: хорошо бы при подсчете кармы исключить или хотя бы понизить степень кармадрочерства. Когда десять разных человек изменили карму — это ведь всяко ценнее, чем когда десять раз изменил карму один и тот же. Можно было бы считать так:
стоимость плюса под номером n:
Cost(n) = 1 / n
суммарная стоимость n плюсов:
Total(n) = Cost(1) + Cost(2) + … + Cost(n) = 1 + 1 / 2 + 1 / 3 + … + 1 / n = n-ое гармоническое число
Это можно было бы назвать кармадрочерской поправкой.
А еще можно было бы вычислить, насколько к данному случаю поправка применима, посчитав степень кармадрочерства, скажем, через разницу времени между постами. Шесть часов — стопроцентное кармадрочерство, 10 суток — нулевое. Соответственно, при стопроцентном кармадрочерстве стоимость изменения кармы считается по кармадрочерской поправке, при нулевом — по обычной формуле (1 для плюсов и 1.5 для минусов).
Тогда формула будет выглядеть так (сисярп, если чо):
double PositiveCoeff = 1; // коэффициент для положительной кармы
double NegativeCoeff = 1.5; // коэффициент для отрицательной кармы
int MinHours = 6; // минимальный промежуток времени для кармы (при нем кармодрочерство — 100%): 6 часов
int MaxHours = 240; // максимальный промежуток времени для кармы (при нем кармодрочерство — 0%): 240 часов (10 дней)
double WeightedKarma(int value) // карма с учетом коэффициентов
{
return value >= 0 ? value * PositiveCoeff : -value * NegativeCoeff;
}
double KarmafagCoeff(DateTime first, DateTime second) // коэффициент кармодрочерства, получаемый из разницы во времени
{
double hours = (second - first).TotalHours;
if (hours < MinHours) // минимальный промежуток — меньше не бывает, но вдруг?
hours = MinHours;
if (hours > MaxHours) // максимальный промежуток
hours = MaxHours;
return (double)(MaxHours - hours) / (MaxHours - MinHours);
}
double KarmafagCost(int number) // формула стоимости оценки для кармодрочера
{
return 1.0 / number;
}
double TotalKarma(IEnumerable<KarmaChange> items) // суммарная карма по всем оценкам от одного пользователя
{
double total = 0;
DateTime? prev = null;
int index = 0;
foreach (KarmaChange item in items) // проходим по всем изменениям кармы
{
index++; // порядковый номер элемента
if (prev == null)
total += WeightedKarma(item.Value);
else
{
double karmafagCoeff = KarmafagCoeff((DateTime)prev, item.DateTime); // коэффициент кармадрочерства для текущего элемента
double karmafagCost = KarmafagCost(index); // стоимость голоса, если он на 100% кармадрочерский
double karmafagCorrection = karmafagCoeff * (karmafagCost - 1) + 1; // кармадрочерская поправка с учетом коэффициента кармадрочерства
total += WeightedKarma(item.Value) * karmafagCorrection; // кармадрочерская поправка, умноженная на взвешенную карму
};
prev = item.DateTime;
};
return total;
}